home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CreatingGames / GameCreators / TADS / Version.doc < prev   
Encoding:
Text File  |  1996-11-22  |  159.2 KB  |  3,535 lines

  1. TADS 2.2.1.0
  2. Unix Patchlevel 1
  3. 18-Oct-96
  4.  
  5. Mike Roberts has made source code to TADS generally available, so I have
  6. merged my Unix changes into the general source distribution as of this
  7. version.
  8.  
  9. This version also includes a bug fix:
  10.  
  11. Fixed a bug in the command parser that caused commands ending with numbers
  12. (e.g., "footnote 1", "undo 5") to confuse the parser. 
  13.  
  14. Also disabled swapping by default, since Unix machines will do better using
  15. their virtual memory.  To force swapping, use the -t+ option.
  16.  
  17. See tadsver.dos for changes from 2.2.0.5 to 2.2.1.0 that apply to all
  18. systems.
  19.  
  20. TADS 2.2.0.5
  21. Unix Patchlevel 1
  22. 22-Nov-94 
  23.  
  24. Fixed a bug that caused window sizes > 135 to crash the run-time.
  25. Increased default buffer sizes.  The defaults that the compiler reports are
  26. actually wrong.  You probably won't have to make any buffers bigger unless
  27. you've got a *really* huge game.
  28.  
  29. See the general 2.2 changes below; there are many important new features.
  30.  
  31. TADS 2.1.2.2
  32. Unix Patchlevel 2
  33. 17-Feb-94
  34.  
  35. Unix pacakges now include the standard documentation.
  36.  
  37. Fixed a bug that caused commands like
  38.  
  39. >X, give me the Y
  40.  
  41. to crash the run-time.
  42.  
  43.  
  44. TADS 2.1.2.2
  45. Unix Patchlevel 1
  46. 29-Jan-94
  47.  
  48. Unix-specific changes applied to latest TADS source.  Unix versions 2.1.0.0
  49. pl2 through pl4 were never released, so please read the notes for those as
  50. well -- this is the first release version that incorporates those changes.
  51.  
  52. The window-resizing code seems to have been broken.  Resizing the window
  53. sends the run-time into space.  I'm looking into it.  For now, don't change
  54. the window size while playing.
  55.  
  56. adv.t and std.t have been updated to 2.1.2.2 as well.
  57.  
  58.  
  59. TADS 2.1.0.0
  60. Unix Patchlevel 4
  61. 16-Nov-93
  62.  
  63. Changed the runtime and compiler so that the heapsize is always set to the
  64. maximum.  An explicit -mh setting will override this.  Note that you cannot
  65. make the heap bigger than 64K, since TADS has to run under DOS in real
  66. mode, where data structures can only be 64K or smaller.
  67.  
  68.  
  69. TADS 2.1.0.0
  70. Unix Patchlevel 3
  71. 25-Oct-93
  72.  
  73. The adv.t and std.t files have been updated to 2.1.0.0.  The ones in the
  74. earlier archives were actually the 2.0.13 ones.  (Doh!)
  75.  
  76. Now tadsr tries to save the game to file "fatal#####.sav" when it gets a
  77. fatal signal, where ##### is the process ID.  Sometimes this file will be
  78. unuseable; other times it'll work fine -- it depends on where the signal
  79. occurs during execution.
  80.  
  81. Two environment variables now affect the behavior of the runtime:
  82.  
  83.     TADSSAVE: directory for save files
  84.         TADSGAME: directory for game files
  85.  
  86. These pathnames will be prepended to any save or game file that does not
  87. already have a slash in it.  For example, if
  88.  
  89.         TADSGAME=~you/games
  90.  
  91. and you type
  92.  
  93.      tadsr foo
  94.  
  95. the run-time will look for the file ~you/games/foo.gam.  Note that if you
  96. want to prevent this, you have to explictly put a ./ in the filename, or
  97. unset the TADSGAME environment variable.  The same goes for TADSSAVE.
  98.  
  99. Since some windowing systems clear the screen when the end-of-visual
  100. terminal code is sent out, tadsr now waits for a keypress before it
  101. terminates.  There is no way to disable this -- the run-time now ignores
  102. the -p flag entirely.  You can always see usage (and game endings) now,
  103. however, which is a plus!
  104.  
  105. The Emacs-style command line editing now handles ^D (delete character after
  106. cursor) and ^K (delete to end of line).
  107.  
  108. Since most Unix boxes have loads of real memory and even more virtual
  109. memory, I increased the size of the scrollback buffer eightfold.  It's now
  110. 256K.  This should be enough for marathon play sessions.
  111.  
  112. There are some known problems with the compiler -- core dumps on at least
  113. one big game, and core dumps when dealing with precompiled headers and
  114. modify/replace in another case.  I haven't been able to track these down,
  115. but they aren't restricted to one architecture.
  116.  
  117. One thing that's been reported as a bug but isn't: If you have the margin
  118. bell on in your xterm you'll get lots of rings as TADS updates the screen.
  119. The solution: turn off the margin bell!
  120.  
  121.  
  122. TADS 2.1.0.0
  123. Unix Patchlevel 2
  124.  
  125. Output handling has been improved again.  Terminal settings are restored
  126. properly upon suspend (^Z) or resume.  I improved a few other things that I
  127. don't remember now.  :)
  128.  
  129.  
  130. TADS 2.1.0.0
  131. Unix Patchlevel 1
  132.  
  133. The programs should now be quite stable on all supported platforms.
  134. Term handling has been vastly improved, so that the run-time should be
  135. comfortable over a 2400 baud connection.  The compiler now avoids
  136. all the screen handling stuff and just uses stdio for all output.
  137.  
  138. Starting with this release, Unix versions will be given patchlevel
  139. numbers in addition to the standard High Energy version number.
  140. There's one patch number of the general Unix sources, and another for
  141. the specific platform the binaries were compiled for.
  142.  
  143. General Unix notes:
  144.  
  145. The .GAM files are now 100% portable across platforms.  You can compile
  146. a game on a PC clone or Mac and then run the resulting .GAM directly
  147. under Unix (and vice versa).  Kudos to High Energy for that!
  148.  
  149. There is no maketrx program for the Unix versions.  Now that TADS is
  150. running on a much wider range of machines, creating binaries specific
  151. to a particular machine seems rather foolish, so I have not kept
  152. support for doing that in the this port.
  153.  
  154. The TADS run-time uses termcap routines for all output.  You will
  155. therefore need to run it on a terminal with window scrolling capability
  156. (i.e., most modern terminals).  If you find that the programs don't
  157. work properly with your terminal, please let me know -- termcap hacking
  158. is very error-prone, so I may have made a mistake in there somewhere.
  159. Before assuming that the problem is with the TADS run-time, however,
  160. try other programs on your system that use termcap, like vi.  (Emacs
  161. has its own term handling code, so it's not a good test.)
  162.  
  163. There a few things special to the Unix versions:
  164.  
  165.     o (Limited) Emacs-style command line editing:
  166.  
  167.         ^F    ahead one character
  168.         ^B    back one character
  169.         ^A    beginning of line
  170.         ^E    end of line
  171.         ^P    previous command in command list
  172.         ^N    next command in command list
  173.         ^K    kill to end of line
  174.         ^D    delete character after cursor
  175.  
  176.     o ESC enters scrollback mode (instead of F1).  Scrollback control
  177.       keys are listed on the top line.
  178.  
  179.     o Press ^L at any time to redraw the entire screen (if you
  180.       get a burst of line noise, for example)
  181.  
  182.     o Press ^Z (or whatever your SIGTSTP key is) to suspend the 
  183.       run-time.
  184.  
  185.     o tadsr recognizes SIGWINCH so that you can resize your
  186.       terminal window.  Text above the current line won't be
  187.       reformatted when you do this, but all subsequent text
  188.       will be formatted to fill the screen.  
  189.  
  190.       NOTE: Resize doesn't work in an OpenWindows cmdtool.
  191.  
  192. The output handling is still not absoultely optimal, but it's probably
  193. as good as it's going to get since the machine-independent TADS source
  194. imposes certain requirements on the behavior of the windowing functions.
  195.  
  196. Finally, please report bugs directly to the person listed as the
  197. maintainer for the port in the banner, not to High Energy.  That person
  198. is the only one (besides, perhaps, me) who's going to be fixing any
  199. problems specific to the Unix ports.
  200.  
  201. Dave Baggett
  202. dmb@ai.mit.edu
  203.  
  204. *-----------------------------------------------------------------------------*
  205. General TADS notes (From the DOS version)
  206. *-----------------------------------------------------------------------------*
  207.  
  208. This file contains a list of changes that have been made to TADS
  209. since the initial 2.0 release.  Most of the changes are fixes to
  210. bugs, so they don't change the documented behavior, but a few, as
  211. explained below, add new functionality to TADS.  Releases are
  212. listed with the most recent release first; each release incorporates
  213. all new features and bug fixes of each prior release unless
  214. otherwise stated.
  215.  
  216. 2.2.1.0  10/01/96  minor corrections, numbered object enhancement
  217.  
  218.   - Note that there has never been an "official" version 2.2.0.5;
  219.     some versions with that designation have appeared on a few
  220.     platforms to expedite the release of some bug fixes, but 2.2.0.5
  221.     was never universally released.  To eliminate any confusion, this
  222.     release is designated 2.2.1.0, and should incorporate all of the
  223.     bug fixes of and be upwardly compatible with any versions labelled
  224.     2.2.0.5.
  225.  
  226.   - The player command parser has a new feature that allows you to use
  227.     numbered objects without specifying in advance an object for each
  228.     possible number.  For example, if you want to design an elevator
  229.     with 100 buttons for floors, you can now create a single button
  230.     for all of the 100 buttons.
  231.  
  232.     The new feature uses a special new adjective property setting, '#'.
  233.     For example:
  234.  
  235.          elevatorButton: fixeditem
  236.              noun = 'button'
  237.              plural = 'buttons'
  238.              adjective = '#'
  239.              location = elevator
  240.          ;
  241.     
  242.     The special adjective '#' tells the parser that the object can be
  243.     used with any number.  The parser accepts the syntax "button 100"
  244.     and "100 button" as equivalent, just as it would if you had specifically
  245.     included '100' as an adjective with the object -- in other words,
  246.     the adjective '#' behaves the same way that regular numeric adjectives
  247.     behave.
  248.  
  249.     When the player refers to the button in a command, the parser requires
  250.     a number to be used.  If the player refers to the button without a
  251.     number, the parser displays error number 160, "You'll have to be more
  252.     specific about which %s you mean" (where "%s" is replaced with the
  253.     phrase the player entered that referred to the button).  You can
  254.     customize message 160 with parseError as with any other message.
  255.  
  256.     If the player properly enters a number with the object name (by
  257.     typing, for example, "button 99"), the parser calls a new method in
  258.     the object:  newNumbered(actor, v, num) -- "actor" is the actor
  259.     for the command (Me if the command was not explicitly directed to
  260.     another actor), "v" is the verb object, and "num" is a number
  261.     typed by the player.  "num" can also be nil:  if the player refers
  262.     to the button with a plural ("look at buttons"), the parser calls
  263.     newNumbered with nil instead of a number to indicate that the player
  264.     wants to refer to all such objects collectively.
  265.  
  266.     The newNumbered method must return either an object or nil.  If it
  267.     returns nil, the method should first display an error message -- the
  268.     parser will simply cancel the command without any further messages
  269.     if newNumbered returns nil.  If newNumbered returns an object, the
  270.     parser uses this object (instead of the elevatorButton object itself)
  271.     as the numbered object.
  272.  
  273.     adv.t includes a new class, numberedObject, that you can use to
  274.     implement numbered objects.  This class provides a newNumbered
  275.     method that creates a copy of the object, and sets its value
  276.     property to the number the player used to refer to the object --
  277.     for example, if the player types "button 99," newNumbered will
  278.     create a copy of the button, and the copy's "value" method will
  279.     return the numeric value 99.  The newNumbered method defined in
  280.     numberedObject calls another method, num_is_valid(num), to
  281.     determine if the number is valid; if this method returns true,
  282.     newNumbered proceeds, otherwise it returns failure.  By default,
  283.     num_is_valid(num) returns true; you can override this method if
  284.     you want to restrict the range of valid numbers.  For example,
  285.     you would define the elevator button's num_is_valid as follows:
  286.  
  287.         num_is_valid(num) =
  288.         {
  289.             if (num < 1 or num > 100)
  290.             {
  291.             "The buttons are numbered from 1 to 100.";
  292.         return nil;
  293.             }
  294.             else
  295.             return true;
  296.         }
  297.  
  298.     The newNumbered method returns the original object by default if
  299.     the player refers to the object with a plural; if you wish to use
  300.     another object to handle plural references, override the method
  301.     newNumberedPlural(actor, v) to return a different object, or nil
  302.     (after displaying an appropriate error message) if you don't want
  303.     to allow plural references at all.  You may want to handle plural
  304.     references with a different object if you want plural references
  305.     to work very differently -- in other words, if you want actions
  306.     taken on all such objects collectively to have special handling.
  307.  
  308.     The numberedObject defines dobjGen and iobjGen routines that
  309.     don't allow any actions to be taken on the object in the plural;
  310.     they do this by checking to see if the value property is nil,
  311.     which indicates that this is the original (plural) object.  These
  312.     methods simply display "You'll have to be more specific about
  313.     which one you mean" and otherwise ignore the command when the
  314.     player uses the plural object.  You may want to override this
  315.     behavior for some verbs.  For example, the elevator button's
  316.     dobjGen should probably be defined like this:
  317.  
  318.         dobjGen(a, v, i, p) =
  319.     {
  320.         if (self.value <> nil or v <> inspectVerb)
  321.             inherited.dobjGen(a, v, i, p);
  322.         else if (v == inspectVerb)
  323.         {
  324.             "The boxes are numbered 1000 to 9999.";
  325.         exit;
  326.         }
  327.     }
  328.  
  329.     This allows the player to get some useful information from "look
  330.     at buttons," but doesn't allow commands such as "push all buttons."
  331.  
  332.     Note that the implementation of newNumbered in numberedObject
  333.     automatically sets a fuse to delete the newly created object at
  334.     the end of the command.  Therefore, you can't use the new objects
  335.     to contain any state that you want to persist after the end of the
  336.     command.
  337.  
  338.     For the elevator button example, the only thing you really need to
  339.     remember is whether a particular button is lit up or not.  You could
  340.     do this with a list.  When the game is first starting up, you could
  341.     initialize this list like this:
  342.  
  343.         local i;
  344.         elevator.button_list := [];
  345.         for (i = 1 ; i < 10 ; ++i)
  346.             elevator.button_list += [nil nil nil nil nil nil nil nil nil nil];
  347.  
  348.     Now you can define the button's doPush method like this:
  349.  
  350.         doPush(actor) =
  351.         {
  352.             if (elevator.button_list[value])
  353.                 "It's already lit.";
  354.             else
  355.                 elevator.button_list[value] := true;
  356.         }
  357.  
  358.     The parser uses one additional method in some circumstances.  When
  359.     the player uses "any" with an object whose adjective list contains
  360.     '#', the parser evaluates the property anyvalue(n) for the object.
  361.     The parameter "n" is a number indicating how many of these objects
  362.     has been requested so far for this command.  Currently, it's always
  363.     1; in the future, a command such as "push any 3 buttons" may call
  364.     this method three times, with "n" set to 1, 2, and 3, respectively,
  365.     for the three calls.  For the time being, "push any 3 buttons" is
  366.     treated by the parser as identical with "push buttons".  The
  367.     default implementation of anyvalue in numberedObject in adv.t
  368.     simply returns the same number "n" that it received as a parameter;
  369.     if your valid number range doesn't start with 1, you should override
  370.     this method to return a number in your object's valid range.
  371.  
  372.   - The compiler now generates more useful errors for undefined objects.
  373.     In particular, errors for objects that are used in class lists but
  374.     never defined now include the name of the undefined object and the
  375.     source file location of the first use.  In addition, the compiler
  376.     now lists all undefined object errors with a line number prefix giving
  377.     the actual line of the error, rather than providing that information
  378.     parenthetically in the error message as it did formerly.  In
  379.     addition, the compiler now checks for undefined objects even when
  380.     other errors are encountered, increasing the likelihood that you
  381.     can find all errors on the first compile.
  382.  
  383.   - The player command parser now allows a word to start with a dash or
  384.     apostrophe (these characters have always been allowed within words;
  385.     now they're allowed at the starts of words, too).
  386.  
  387.   - The system allows format strings (such as %you%) to be used while
  388.     the init() function is active, and uses Me as the current actor for
  389.     translating the format strings.
  390.  
  391.   - Under certain circumstances, the compiler stored the same object/word
  392.     relationship twice for a vocabulary word, causing the parser to list
  393.     the same object more than once in a disambiguation question ("which
  394.     book do you mean...").  This has been corrected.
  395.  
  396.   - The parser's handling of pronouns (it, him, her) has been changed
  397.     slightly.  Previously, the parser always replied "I don't know what
  398.     you're referring to with 'it'" if the antecedant was not accessible
  399.     for the new command (the validDo/validIo routine returned a false
  400.     indication).  The parser now instead uses the standard cantReach
  401.     mechanism that would use if the command were typed with the object
  402.     explicitly.
  403.  
  404.   - The runtime now calls preinit() prior to calling the restart
  405.     callback function if one was provided and the game was compiled for
  406.     debugging.  (The runtime previously called preinit() *after* calling
  407.     the restart callback when the game was compiled for debugging, which
  408.     meant that the game state as seen in the callback was different when
  409.     a game was compiled for debugging than for the same game compiled
  410.     with debugging off, because with debugging off, preinit is run by
  411.     the compiler.  This change makes the state seen by the restart
  412.     callback function the same for both versions of the game.)
  413.  
  414.   - Assignments through property pointers now work properly.
  415.  
  416. 2.2.0  10/30/94  new features, enhancements, bug fixes
  417.  
  418.   - TADS now has support for reading and writing files.  This new
  419.     feature is intended to let you save information independently
  420.     of the game-saving mechanism, which allows you to transfer
  421.     information between sessions of a game, or even between two
  422.     different games.  The TADS file operations are not designed
  423.     as general-purpose file system operations; in particular,
  424.     these new functions don't have any provisions for creating or
  425.     reading formatted files, or for exchanging information with
  426.     programs other than TADS games.
  427.  
  428.     To open a file, use the fopen() function.  This function takes
  429.     two arguments:  a single-quoted string giving the name of the
  430.     file to open, using local file system conventions, and a "mode."
  431.     (For  maximum portability, you should avoid using volume names,
  432.     directories, folders, or other path information in filenames.)
  433.     The mode argument is one of these single-quoted string values:
  434.  
  435.         r    open file for reading; file must already exist
  436.         r+   open file for reading and writing; the file is
  437.              created if it doesn't already exist
  438.         w    create a new file for writing; the file is deleted
  439.              if it already exists
  440.         w+   create a new file for reading and writing; the file
  441.              is deleted if it already exists
  442.  
  443.     The return value of fopen() is a "file handle"; this is simply
  444.     a number that you you to perform subsequent operations on the
  445.     file.   For example, this opens a new file called TEST.OUT for
  446.     writing:
  447.  
  448.         fnum := fopen('test.out', 'w');
  449.  
  450.     To close an open file, use fclose():
  451.  
  452.         fclose(fnum);
  453.  
  454.     Note that the TADS runtime allows only a limited number of
  455.     files (currently 10) to be open simultaneously, so you should
  456.     close a file when you're done with it.
  457.  
  458.     To write to a file, use fwrite().  This function takes a file
  459.     handle, and a value to write; the value can be a string, a number,
  460.     or true.  The value can't be nil (this is because the fread() function
  461.     returns nil to indicate failure; if you could write nil to a file,
  462.     there would be no way to distinguish reading a valid nil from an
  463.     error condition).  fwrite() stores the value, along with information
  464.     on its type.
  465.  
  466.     The fwrite() function returns nil on success, true on failure.  If
  467.     the function returns true, it usually means that the disk is full.
  468.  
  469.        if (fwrite(fnum, 'string value!')
  470.            or fwrite(fnum, 123))
  471.            "Error writing file!";
  472.  
  473.     If the file is open for reading, you can read from the file with
  474.     the fread() function.  This function takes a file handle, and it
  475.     returns a value it reads from the file.  The value returned is
  476.     of the same type as the value originally written at this position
  477.     in the file with fwrite().  If this function returns nil, it
  478.     indicates that an error occurred; this usually means that no more
  479.     information is in the file (you've read past the end of the file).
  480.  
  481.        res := fread(fnum);
  482.        say(res);
  483.  
  484.     You can get the current byte position in the file with the ftell()
  485.     function:
  486.  
  487.        "The current seek position is << ftell(fnum) >>. ";
  488.  
  489.     The ftell() function returns a number giving the byte position
  490.     that will be read or written by the next file operation.
  491.  
  492.     You can set the file position with fseek() and fseekeof().  The
  493.     fseek() function moves the file position to a particular byte
  494.     position, relative to the beginning of the file.  For example,
  495.     this seeks to the very beginning of a file:
  496.  
  497.        fseek(fnum, 0);
  498.  
  499.     The fseekeof() function positions the file at its end:
  500.  
  501.        fseekeof(fnum);
  502.  
  503.     Note that you must be careful with fseek().  You should only seek
  504.     to positions that you obtained with the ftell() function; other
  505.     positions may be in the middle of a string or a number in the
  506.     file, so seeking to an arbitrary location and writing could
  507.     render the file unusable by partially overwriting existing data.
  508.  
  509.   - You can now "capture" displayed text to a string.  This new feature
  510.     allows you to examine and manipulate text displays, no matter how they
  511.     are generated.  To activate capturing, use the new built-in function
  512.     outcapture():
  513.  
  514.         stat := outcapture(true);
  515.  
  516.     This starts capturing text.  The return value is a status code that
  517.     you use in the subsequent call to end capturing; you don't need to do
  518.     anything with this status code except pass it to outcapture() when
  519.     you're finished capturing output.
  520.  
  521.     While capturing is in effect, everything that your game attempts to
  522.     display -- through double-quoted strings or through the say() built-in
  523.     function -- is hidden from the user and instead stored in a string.
  524.     Once outcapture(true) is called, no text will be displayed to the
  525.     user until you call this function:
  526.  
  527.         str := outcapture(stat);
  528.  
  529.     The second outcapture() call turns off capturing, and returns a string
  530.     that contains all of the text that was generated since the corresponding
  531.     outcapture(true).
  532.  
  533.     Note that the system automatically turns off capturing any time it
  534.     prompts the user for information.  The system turns off capturing
  535.     when it starts a new command, or when it needs to prompt the user
  536.     for information during a command, such as for disambiguation or to
  537.     request a missing direct or indirect object.  When the system turns
  538.     off output capturing, it clears the capture buffer, so any subsequent
  539.     call to outcapture(stat) will return an empty string.  You can capture
  540.     text only over the course of a single command line.
  541.  
  542.     The outcapture() function can be useful if you want to save some
  543.     text for later.  It's also useful if you want to be able to examine
  544.     the text that would be generated by a method such as sdesc or ldesc.
  545.     Since these methods directly display text, you can't directly obtain
  546.     a string representation of their values; using outcapture(), however,
  547.     you can let them "display" their values into a string that you can
  548.     then examine.
  549.  
  550.     Note that the status value returned from outcapture(true) allows you
  551.     to nest calls to outcapture().  Since the outcapture(stat) call
  552.     restores the capturing status that was in effect on the corresponding
  553.     call to outcapture(true), you don't have to worry when using outcapture()
  554.     about whether any of the methods you're calling are also using it.
  555.  
  556.   - TADS now allows you to create and delete objects dynamically
  557.     at run-time.  This is done through two new operators:  "new"
  558.     and "delete".
  559.  
  560.     To create a new object, use this syntax:
  561.  
  562.         x := new bookItem;
  563.  
  564.     This dynamically creates a new object whose superclass is bookItem.
  565.     When this statement is executed, the runtime creates a new object,
  566.     assigns its superclass to be bookItem, and executes the "construct"
  567.     method in the new object; this method can perform any creation-time
  568.     setup that's desired.  The default thing.construct in adv.t simply
  569.     moves the new object into its location -- this is necessary so that
  570.     the "contents" list of the location is updated to include the new
  571.     object.
  572.  
  573.     A new object inherits all of the vocabulary of its superclass.
  574.  
  575.     To destroy an object you have created, use this syntax:
  576.  
  577.         delete x;
  578.  
  579.     This first calls the "destruct" method of the object to notify it
  580.     that it is about to be deleted, then destroys the object.  Further
  581.     references to the object are illegal, since its memory has been
  582.     released (and thus may be given to another object).  The default
  583.     thing.destruct in adv.t moves the object into nil, which removes it
  584.     from its container's "contents" list -- this is necessary so that
  585.     the reference to the object in that list is removed.
  586.  
  587.     Only objects created with "new" can be destroyed with "delete".
  588.     Objects that are defined statically in your game's source file
  589.     cannot be deleted at run-time.
  590.  
  591.     Object creation and deletion works correctly with the UNDO
  592.     mechanism.  If the player uses UNDO after a move that created an
  593.     object, the object will be destroyed; likewise, if a player uses
  594.     UNDO after a turn that deletes an object, the object will be
  595.     re-created with the same property values it had prior to deletion.
  596.     Similarly, dynamically-created objects are preserved across SAVE
  597.     and RESTORE operations.
  598.  
  599.     Note that TADS does not perform any garbage collection on
  600.     dynamically-created objects.  The system is not capable of
  601.     determining whether an object is accessible or not.  Hence, if
  602.     you lose track of any objects you create with "new", they will
  603.     remain in memory forever -- they will even be saved along with
  604.     saved games and restored when the games are restored.  You must
  605.     be careful to keep track of all objects you create to avoid
  606.     filling all available memory (and the swap file) with unreachable
  607.     objects.
  608.  
  609.   - It is now possible to dynamically add to and delete from the
  610.     vocabulary words of an object.  You can also get the vocabulary
  611.     words of an object at run-time.
  612.  
  613.     To add to an object's vocabulary, use the new "addword" built-in
  614.     function.  This function takes three arguments:  an object, a
  615.     vocabulary property pointer, and a word to add.  For example,
  616.     to add 'red' as an adjective to the object myBook, you would
  617.     do this:
  618.  
  619.         addword(myBook, &adjective, 'red');
  620.  
  621.     To delete the same word, you would write a similar call to the
  622.     new built-in function "delword":
  623.  
  624.         delword(myBook, &adjective, 'red');
  625.  
  626.     You can add to and delete from the words of any object, including
  627.     both static objects (explicitly defined in your source code) and
  628.     dynamically-created objects (created with the "new" operator).
  629.  
  630.     Changes made by addword and delword are tracked correctly by the
  631.     UNDO mechanism, and are saved and restored along with saved games.
  632.  
  633.     To get the words belonging to an object, use the new "getwords"
  634.     built-in function.  This function takes two arguments:  an object,
  635.     and a property pointer; it returns a list of (single-quoted)
  636.     strings, which are the vocabulary words for the object.  For
  637.     example, assume we define myBook as follows:
  638.  
  639.         myBook:  item
  640.             sdesc = "small red book"
  641.             adjective = 'small' 'red' 'tiny'
  642.             noun = 'book'
  643.             location = room2
  644.         ;
  645.  
  646.     Also assume we haven't made any calls to addword() or delword() for
  647.     myBook.  In this case,
  648.  
  649.         getwords(myBook, &adjective)
  650.  
  651.     would return this list:
  652.  
  653.         ['small' 'red' 'tiny']
  654.  
  655.     Note that the order of the words in the list is not predictable,
  656.     so you shouldn't expect the words to be in the same order as they
  657.     were when you defined them in the source file, or in the same
  658.     order as they were added with addword().
  659.  
  660.   - We've added a new function that lets you get information on a verb.
  661.     The new function is verbinfo().  This function lets you get the
  662.     verification and action properties for a verb.  The new function
  663.     takes one or two arguments:  the first is the deepverb object whose
  664.     information you want to retrieve; the optional second argument is
  665.     a preposition object.  If you call verbinfo() with only the verb
  666.     argument, it returns the verification and action properties that
  667.     are defined with the doAction definition for the verb.  If you
  668.     also include the preposition argument, it returns the properties
  669.     that are defined with the ioAction definition for that preposition.
  670.  
  671.     The value returned by this function is a list.  If you call verbinfo()
  672.     with only the deepverb argument, the list has two elements:
  673.  
  674.       [1]   direct object verification property pointer (verDoXxxx)
  675.       [2]   direct object action property pointer (doXxxx)
  676.  
  677.     If you call verbinfo() with both the verb and preposition arguments,
  678.     the return value is a list with four elements:
  679.  
  680.       [1]   direct object verification property pointer (verDoXxxx)
  681.       [2]   indirect object verification property pointer (verIoXxxx)
  682.       [3]   indirect object action property pointer (ioXxxx)
  683.       [4]   true if ioAction has [disambigDobjFirst] flag, nil otherwise
  684.  
  685.     In either case, if no matching doAction or ioAction definition
  686.     exists for the verb, this function returns nil.
  687.  
  688.     Note that it is possible that additional flags (similar to
  689.     disambigDobjFirst) may be added in the future; the returned list
  690.     may be expanded to include information on any such added flags.
  691.     So, for compatibility with future versions, we recommend that you
  692.     don't write conditional code based on the length of the list.
  693.     The lists will never shrink, but they may expand.
  694.  
  695.     For the removeVerb object defined in adv.t, you would get these
  696.     results:
  697.  
  698.       verbinfo(removeVerb)
  699.         = [&verDoUnwear &doUnwear]
  700.  
  701.       verbinfo(removeVerb, fromPrep)
  702.         = [&verDoRemoveFrom &verIoRemoveFrom &ioRemoveFrom nil]
  703.  
  704.   - The ability to create new objects at run-time leads to some
  705.     interesting problems involving indistinguishable objects.  Although
  706.     you should generally use addword (see below) to make your newly-created
  707.     objects distinguishable from one another, this will not always be
  708.     desirable; for example, if you create new gold pieces that serve
  709.     as currency, you will probably not want them to be uniquely named.
  710.  
  711.     To support indistinguishable objects, especially those created
  712.     dynamically at run-time, the system now has a property that you
  713.     can set to indicate to the parser that an object does not need to
  714.     be distinguished from others of the same class.  The new property
  715.     is "isEquivalent".  When isEquivalent returns true for an object,
  716.     all other objects with the same immediate superclass are considered
  717.     interchangeable by the parser.  When a player uses one of these
  718.     objects in a command, the parser will simply pick one arbitrarily
  719.     and use it, without asking the player which one.
  720.  
  721.     If a player uses a noun that is ambiguous with multiple equivalent
  722.     items and one or more other items, the parser will need to
  723.     disambiguate the objects as usual.  In such cases, the parser's
  724.     question will list the distinguishable items only once.  For
  725.     example, assume we have five gold coins that are all equivalent
  726.     (in other words, they all have isEquivalent set to true, and they
  727.     all are immediate subclasses of the same class).  Assume further
  728.     that a silver coin and a bronze coin are also present in the room.
  729.  
  730.        Treasure Room
  731.            You see a bronze coin, five gold coins, and a silver
  732.        coin here.
  733.  
  734.        >get coin
  735.        Which coin do you mean, the bronze coin, a gold coin, or
  736.        the silver coin?
  737.  
  738.     Note that the objects which appear only once are listed with "the"
  739.     (using the thedesc property), while the indistinguishable objects
  740.     are listed only once, with "a" (using the adesc property).
  741.  
  742.   - The new property pluraldesc has been added to thing in adv.t.
  743.     The definition in thing simply adds an "s" to the end of the
  744.     sdesc property.  This new property is used by listcont(obj)
  745.     when multiple equivalent objects are present in a list; see the
  746.     information on the changes to listcont(obj) for details.
  747.  
  748.   - The adv.t functions listcont(obj) and itemcnt(list) have been
  749.     changed to support indistinguishable objects.  To support this
  750.     new functionality, the new functions isIndistinguishable(obj1, obj2)
  751.     and sayPrefixCount(cnt), and the new property pluraldesc, have
  752.     been added to adv.t.
  753.  
  754.     isIndistinguishable(obj1, obj2) returns true if the two objects
  755.     obj1 and obj2 are equivalent for the purposes of listing.  The
  756.     two objects are considered equivalent if both have the same
  757.     first superclass (the return value of the new built-in function
  758.     firstsc(obj)), either they are both being worn or neither is
  759.     worn, and either both are lit lightsources or neither is.  This
  760.     function doesn't test the isEquivalent property of either object,
  761.     since it's assumed that it will only be called if an object has
  762.     already been found whose isEquivalent property is set.
  763.  
  764.     sayPrefixCount(cnt) displays a number.  If the parameter cnt is
  765.     a small number (from one to twenty), the spelled-out number will
  766.     be displayed (for example, "five" will displayed if cnt = 5).  If
  767.     the count is larger, the number will be displayed as digits ("35"
  768.     will be displayed if cnt = 35).  This function is used by
  769.     listcont(obj) to show the number of equivalent items when more
  770.     than one equivalent item is being listed.
  771.  
  772.     itemcnt(list) now returns the number of distinguishable items in
  773.     the list that are to be listed.  For each item in the list whose
  774.     isEquivalent property is true, itemcnt(list) checks each other
  775.     item in the list, and counts each set of equivalent items only once.
  776.     Hence, if a list consists entirely of equivalent items, itemcnt(list)
  777.     will return at most 1 (it will return 0 if none of the items are
  778.     listable).
  779.  
  780.     listcont(obj) will list each set of indistinguishable items in the
  781.     contents list only once, and will show the number of each such item.
  782.     To display the number, the new function sayPrefixCount(cnt) is
  783.     used.  For example, if a room contains a silver coin, a bronze coin,
  784.     and five gold coins (all with the isListed property set to true),
  785.     listcont(room) will display this:
  786.  
  787.        a silver coin, a bronze coin, and five gold coins
  788.  
  789.   - A new built-in function has been added to make it possible to
  790.     implement the functionality of the new listcont method.  The new
  791.     function, firstsc(obj), returns the first immediate superclass of
  792.     the given object (or nil if the object has no superclass).  This
  793.     function, along with the isEquivalent property, can be used to
  794.     determine if two objects should be considered indistinguishable.
  795.  
  796.   - A new special word has been added:  ANY, which is equivalent to
  797.     EITHER.  These words are at the end of the original specialWords
  798.     list; for compatibility with past versions, a specialWords list
  799.     that omits this position is still legal, and indicates that the
  800.     default ('any' = 'either') should be used for this slot.
  801.  
  802.     This special word slot is used by the parser during disambiguation.
  803.     Whenever the parser asks the player to choose an object from a list
  804.     of ambiguous objects, it will accept ANY:
  805.  
  806.         >take coin
  807.         Which coin do you mean, the silver coin, the bronze coin, or
  808.         the gold coin?
  809.  
  810.         >any
  811.         silver coin:  Taken.
  812.  
  813.     When ANY is used in these cases, the parser will simply pick one
  814.     of the objects arbitrarily.  Note that it displays the chosen
  815.     object in the same manner as it would if multiple objects were
  816.     being used.
  817.  
  818.     In addition, the parser will accept noun phrases that start with
  819.     ANY to indicate that any object matching the given noun phrase is
  820.     acceptable; the parser will choose one of the objects arbitrarily
  821.     in these cases.  For example:
  822.  
  823.         >take any coin
  824.         silver coin:  Taken.
  825.  
  826.         >look at any of the coins
  827.         bronze coin:  It's a valuable 1964 Tadsmid, worth over
  828.         .0004 cents on today's scrap bronze market.
  829.  
  830.     The player can also specify the number of items to take.  When
  831.     a number of items is specified, it must be applied to a plural
  832.     noun phrase, and it means the same thing as "any," except that
  833.     the parser (arbitrarily) chooses the given number of items rather
  834.     than just one.  For example:
  835.  
  836.     >look at 3 coins
  837.     >look at any 3 coins
  838.     >look at 3 of the coins
  839.     >look at any 3 of the coins
  840.  
  841.     As a special case, a count of "1" can be used with a singular
  842.     noun phrase.  It means the same thing as "any."
  843.  
  844.         >look at 1 coin
  845.  
  846.   - A new convenience feature, similar to doSynonym and ioSynonym but
  847.     somewhat easier to use, has been added.  You can now specify that
  848.     a method in one object should instead be sent to another object.
  849.     An example:
  850.  
  851.         desk: fixeditem
  852.             noun = 'desk'
  853.             sdesc = "desk"
  854.             location = office
  855.             doOpen -> deskDrawer
  856.             doClose -> deskDrawer
  857.         ;
  858.  
  859.     This specifies that doOpen, verDoOpen, doClose, and verDoClose
  860.     calls should be sent to the deskDrawer object when received by
  861.     the desk.  Note that this should only be used for standard verb
  862.     handler methods, because it redirects both the method indicated
  863.     and its verXoVerb equivalent.
  864.  
  865.   - The parser calls a new method, multisdesc, when displaying the
  866.     name of an object that's part of a list of objects.  Previously,
  867.     the parser simply used sdesc in these cases.  The default adv.t
  868.     definition of thing.multisdesc simply calls the object's sdesc.
  869.     This new method is intended to allow you greater control over
  870.     the display in situations like this:
  871.  
  872.       >get all
  873.       book:  Taken.
  874.       rug:  That's much too heavy to carry.
  875.  
  876.     The object names listed before the colons are now displayed
  877.     with multisdesc.
  878.  
  879.     For compatibility with old games, if an object being listed does
  880.     not define or inherit a multisdesc property, its sdesc is used
  881.     instead.  This ensures that games compiled with previous versions
  882.     of adv.t will continue working properly.
  883.  
  884.   - A new user-defined function that the parser calls has been added.
  885.     This new function is called preparseCmd(), and is similar to
  886.     preparse().  Whereas preparse() is called once for an entire
  887.     command line, and is called with the original, unfiltered text
  888.     of the player's command line, preparseCmd() is called separately
  889.     for each command on a command line if more then one command is
  890.     entered.  Furthermore, preparseCmd() is called after the command
  891.     has been "tokenized" (broken into individual words).  Whereas the
  892.     argument to preparse() is a string with the entire command line,
  893.     the argument to preparseCmd() is a list, each entry of which is
  894.     a (single-quoted) string giving an individual word.  Using the new
  895.     function, you can exert much greater control over how a command
  896.     is parsed, including rewriting a command entirely.
  897.  
  898.     preparseCmd() is called immediately before Me.roomCheck() is called
  899.     for the command.  This call is made prior to any disambiguation or
  900.     object defaulting.
  901.  
  902.     If preparseCmd() returns nil, the command is abandoned (but no
  903.     error message is displayed), and no fuses or daemons are run.  If
  904.     the function returns true, the command proceeds as normal.  Any
  905.     remaining commands on the same line are executed regardless of the
  906.     return value from preparseCmd().  (If you need to cancel the entire
  907.     rest of the command line, one approach would be to set a property
  908.     in the global object to indicate to preparseCmd() that all commands
  909.     are to be ignored; preparseCmd() would always check this property
  910.     before doing anything else, and return nil if it were set.  You
  911.     could clear this property in preparse() so that commands always
  912.     start off enabled.)
  913.  
  914.     In addition, preparseCmd() can return a list of (single-quoted)
  915.     strings, in which case the parser starts over parsing the list
  916.     instead of the original command.  The list is limited to a maximum
  917.     of 128 characters, with one additional character of overhead per
  918.     word -- in other words, you can't make the new command longer
  919.     than the original command, which is limited to the same maximum
  920.     when entered by the player in the first place.  However, you can
  921.     otherwise rewrite the command entirely.  If you want to include
  922.     any special words in the new command, use the conventions described
  923.     below (for example, if you want to include 'and' in the new command,
  924.     use ',' instead).  After the new command inserted by preparseCmd()
  925.     has been processed, the parser will resume processing any remaining
  926.     commands on the player's original command line.
  927.  
  928.     The new command list returned by preparseCmd() can contain multiple
  929.     commands.  Simply separate the commands with commas (',') in your
  930.     list.
  931.  
  932.     If preparseCmd() returns a list, preparseCmd() will be invoked on
  933.     the new command.  However, preparseCmd() is not allowed to return
  934.     another new command in these cases -- if it does, the parser will
  935.     assume that preparseCmd() is looping, and will generate an error.
  936.  
  937.     Several new parseError codes have been added to respond to error
  938.     conditions that can arise from preparseCmd():
  939.  
  940.         32  Internal game error: preparseCmd returned an invalid list
  941.         33  Internal game error: preparseCmd command too long
  942.         34  Internal gmae error: preparseCmd loop
  943.  
  944.     The sample implementation of preparseCmd() below simply lists all
  945.     of the words in the current command and displays a newline, then
  946.     allows the command to proceed as usual.
  947.  
  948.         #pragma C+
  949.         preparseCmd: function(cmd)
  950.     {
  951.         local i, tot;
  952.     
  953.         for (i = 1, tot = length(cmd) ; i <= tot ; ++i)
  954.             "<<cmd[i]>> ";
  955.         "\n";
  956.         
  957.             return true;
  958.     }
  959.  
  960.     Note that the parser performs conversions of the special words.
  961.     These conversions will show up in the list as follows:
  962.  
  963.         "and"   becomes  ","
  964.         "all"   becomes  "A"
  965.         "but"   becomes  "X"
  966.         "it"    becomes  "I"
  967.         "them"  becomes  "T"
  968.         "him"   becomes  "M"
  969.         "her"   becomes  "R"
  970.         "any"   becomes  "Y"
  971.  
  972.     Here are some examples using the preparseCmd() function above.
  973.     (The actual response of the commands has been removed -- only the
  974.     text displayed by preparseCmd() is shown.)
  975.  
  976.         >look at all
  977.         look at A
  978.  
  979.         >examine him; take everything except the box and the book and go north
  980.         examine M
  981.         take A X the box , the book
  982.         go north
  983.  
  984.     preparseCmd() is called even for commands that the parser doesn't
  985.     understand.  This allows you to rewrite commands that TADS wouldn't
  986.     normally understand and put them into a format that's acceptable to
  987.     the parser.  For example, the preparseCmd() example below will
  988.     take sentences of the form "tell <actor> to <command>", and convert
  989.     them to the normal TADS syntax, "<actor>, <command>".
  990.         
  991.         #pragma C+
  992.         preparseCmd: function(cmd)
  993.     {
  994.         local i, tot, to_loc, actor, the_rest;
  995.  
  996.             tot = length(cmd);
  997.  
  998.         /* check to see if it starts with "tell" */
  999.         if (tot > 3 && cmd[1] == 'tell')
  1000.         {
  1001.             /* see if there's a word "to" */
  1002.         for (i = 1, tot = length(cmd) ; i <= tot ; ++i)
  1003.         {
  1004.             if (cmd[i] == 'to')
  1005.                 to_loc = i;
  1006.         }
  1007.  
  1008.         /* if there's a "to", convert the command */
  1009.         if (to_loc != nil && to_loc > 2)
  1010.         {
  1011.             /* find the parts before and after the 'to' */
  1012.             for (i = 2, actor = [] ; i < to_loc ; ++i)
  1013.                 actor += cmd[i];
  1014.             for (the_rest = [], i = to_loc + 1 ; i <= tot ; ++i)
  1015.                 the_rest += cmd[i];
  1016.  
  1017.             /* convert it to "actor, command" */
  1018.             return actor + ',' + the_rest;
  1019.         }
  1020.         }
  1021.  
  1022.             /* otherwise, process the command as normal */
  1023.             return true;
  1024.         }
  1025.  
  1026.     When the parser doesn't know how to handle a sentence, it calls
  1027.     preparseCmd with the entire rest of the command (which will include
  1028.     everything before the next THEN or period), and processing is the
  1029.     same as in any other case.  If preparseCmd() returns nil in this
  1030.     case, the command is cancelled as usual without any further
  1031.     processing by the parser.  If preparseCmd() returns true when the
  1032.     sentence is not recognized by TADS, the parser will display the
  1033.     usual message (parseError code 18, "I don't understand that
  1034.     sentence").  If preparseCmd() returns a list of strings, the
  1035.     command is replaced with the list, and the parser starts over
  1036.     processing the new command.
  1037.  
  1038.   - Several new parseError codes have been added.
  1039.  
  1040.     In order to produce better messages when actors are involved,
  1041.     the system now attempts to figure out whether an object in a
  1042.     command refers to an actor, and if so, to determine whether the
  1043.     actor should be called "him" or "her".  Previously, this
  1044.     one-size-fits-all message was generated:
  1045.  
  1046.        What do you want to <verb> it <prep>?
  1047.  
  1048.     for example:
  1049.  
  1050.        >hit bill
  1051.        What do you want to hit it with?
  1052.  
  1053.     Although it's not always possible to determine which object
  1054.     should be used in these cases (because disambiguation will not
  1055.     be possible until the indirect object is known), the system will
  1056.     make its best guess.  To do so, it looks at all of the objects
  1057.     that might be involved, based on the vocabulary.  If the player
  1058.     appears to mean multiple objects, " them " will be used -- this
  1059.     is message number 144 for parseError:
  1060.  
  1061.        >throw ball and bat
  1062.        What do you want to throw them at?        <- message 144
  1063.                                 ------
  1064.  
  1065.     If only one object appears to be intended, the parser will try
  1066.     to figure out whether the object is male, female, or neuter,
  1067.     using the isHim and isHer properties (these properties are not
  1068.     new; they have been around since before TADS 2.0).  If all of
  1069.     the objects that match a single noun phrase have isHim and
  1070.     not isHer, " him " will be used -- this is parseError message
  1071.     number 145:
  1072.  
  1073.       >hit bill
  1074.       What do you want to hit him with?          <- message 145
  1075.                              -----
  1076.  
  1077.     If they all have isHer and not isHim, " her " will be used
  1078.     (message number 146):
  1079.  
  1080.       >hit jill
  1081.       What do you want to hit her with?          <- message 146
  1082.                              -----
  1083.  
  1084.     If both are set, the system equivocates with " them ", message
  1085.     number 147 (note that this is the same default text as message
  1086.     144, but it's distinguished as a separate message number in
  1087.     case a game author wants a more suitable word in this case,
  1088.     especially in a non-English language):
  1089.  
  1090.       >hit hermaphrodite
  1091.       What do you want to hit them with?         <- message 147
  1092.                              ------
  1093.  
  1094.     If not all of the objects involved have isHim and/or isHer
  1095.     set, the system uses "it" (message 141) as in previous versions.
  1096.  
  1097.     Another change to the processing for this message involves
  1098.     actors.  If an actor is specified in the command, the system
  1099.     now builds a replacement for message 140.  First, message
  1100.     148 is displayed, which has the default text "What do you want ".
  1101.     Then, the actor's thedesc is invoked to display the actor's
  1102.     name.  Finally, message 149 (default text " to ") is displayed,
  1103.     and the rest of the message is built as before.
  1104.  
  1105.       >guard, throw ball
  1106.       What do you want the guard to throw it at?
  1107.       -----------------         ----
  1108.          message 148             149
  1109.  
  1110.   - The functionality of the parseAskobj function has been extended
  1111.     so that you can generate the same sort of message that the parser
  1112.     now generates when a missing object is needed for a command directed
  1113.     to an actor.  To provide the new functionality, the parser now calls
  1114.     a function called parseAskobjActor.  This function is exactly the
  1115.     same as parseAskobj, except that it takes the actor as the first
  1116.     parameter, the verb as the second parameter, and the preposition
  1117.     as an optional third parameter (which is only present when asking
  1118.     for an indirect object).
  1119.  
  1120.     If your game defines parseAskobjActor, the system ignores parseAskobj
  1121.     and calls the new function instead.  If parseAskobjActor is not defined,
  1122.     but parseAskobj is defined, the system calls parseAskobj as it did in
  1123.     past versions.  If neither function is defined, the system generates
  1124.     the message itself as described above.  You should use parseAskobjActor
  1125.     rather than parseAskobj for new games, since it gives you more
  1126.     information.
  1127.  
  1128.     Here's an example of parseAskobjActor, which generates roughly the
  1129.     same message as the system would (but it doesn't do any of the checking
  1130.     of isHim and isHer to determine which pronoun to use -- this function
  1131.     simply uses "it").
  1132.  
  1133.     parseAskobjActor: function(a, v, ...)
  1134.     {
  1135.         if (argcount == 3)
  1136.         {
  1137.             "What do you want ";
  1138.                 if (a <> Me) a.thedesc;
  1139.         " to <<v.sdesc>> it <<getarg(3).sdesc>>?";
  1140.         }
  1141.         else
  1142.         {
  1143.         "What do you want ";
  1144.             if (a <> Me) a.thedesc;
  1145.         " to <<v.sdesc>>?";
  1146.         }
  1147.     }
  1148.  
  1149.   - The parser has been changed slightly to allow a command to specify
  1150.     an actor in any command within a single line containing multiple
  1151.     commands.  Previously, if an actor was to be specified, the actor
  1152.     had to be specified at the very beginning of the command.  This
  1153.     restriction has been removed, which allows commands like this:
  1154.  
  1155.       >joe, north.  bob, south.  bill, east, take book, west.
  1156.  
  1157.     Note that, as in past versions, once an actor is specified, the
  1158.     actor remains in effect for subsequent commands.  Since you could
  1159.     only specify one actor for an entire command line in past versions,
  1160.     this meant that the actor was used for every command on the line;
  1161.     with this new version, an actor remains in effect until another
  1162.     actor is specified.  So, in the command above, "north" is directed
  1163.     to Joe, "south" is directed to Bob, and "east, take book, west"
  1164.     is directed to Bill.
  1165.  
  1166.   - The maximum number of notifiers has been increased to 200.  The
  1167.     maximum number of daemons and fuses has been increased to 100 each.
  1168.  
  1169.   - The maximum number of ambiguous words matching a particular
  1170.     vocabulary word has been increased to 200.  This should relieve
  1171.     problems that some people have reported with the error message
  1172.     "The word 'foo' refers to too many objects".
  1173.  
  1174.   - The compiler now supports most of the remaining C operators:
  1175.  
  1176.         a % b      - returns the remainder of dividing a by b
  1177.         a %= b     - sets a to a % b
  1178.         a != b     - equivalent to a <> b
  1179.         !a         - equivalent to (not a)
  1180.         a & b      - bitwise AND
  1181.         a &= b     - sets a to the bitwise AND of a and b
  1182.         a | b      - bitwise OR
  1183.         a |= b     - sets a to the bitwise OR of a and b
  1184.         a && b     - equivalent to (a and b)
  1185.         a || b     - equivalent to (a or b)
  1186.         a ^ b      - bitwise XOR of a and b
  1187.         a ^= b     - sets a to the bitwise XOR of a and b
  1188.         ~a         - bitwise negation of a
  1189.         a << b     - a shifted left by b bits
  1190.         a <<= b    - shifts a left by b bits
  1191.         a >> b     - a shifted right by b bits
  1192.         a >>= b    - shifts a right by b bits
  1193.  
  1194.     Note a slight complication involving the >> operator:  you can't
  1195.     use this operator from within an embedded string expression, because
  1196.     it would be confused by the parser for the end of the expression.
  1197.     It doesn't help to use parentheses, since the embedded string
  1198.     processing is essentially a textual substitution mechanism which
  1199.     happens without knowledge of the expression context (and is thus
  1200.     unaware of parenthesization).  For example, this would be illegal:
  1201.  
  1202.        myprop = "x divided by 128 is << (x >> 7) >>!"     // wrong
  1203.  
  1204.     You would have to code this instead as:
  1205.  
  1206.        myprop = { "x divided by 128 is "; x >> 7; "!"; }  // right
  1207.  
  1208.     Another slight complication arises from the use of the & operator
  1209.     in lists.  Since TADS allows list elements to appear without any
  1210.     separating punctuation (except whitespace), you can have a list
  1211.     that looks like this:
  1212.  
  1213.        mylist = [&sdesc &adesc &thedesc]
  1214.  
  1215.     This construct is still legal, and is still interpreted with the
  1216.     "&" operators as unary operators, not bitwise AND operators.
  1217.     However, the parser now warns when such a definition is used; see
  1218.     the description of the new warning TADS-357 below for details.
  1219.  
  1220.   - The compiler will generate a new warning when it detects a unary
  1221.     operator within a list that could also be interpreted as a binary
  1222.     operator.  For example, in this list,
  1223.  
  1224.        list2 = [5 -2 -6 -7]
  1225.  
  1226.     the "-" operators could be interpreted either as unary negation
  1227.     operators, which would result in a list with four elements (the
  1228.     numbers 5, -2, -6, and -7), or as binary subtraction operators,
  1229.     which would result in a list with only one element (the number
  1230.     -10).  This same problem arises with the operators "+" and "&",
  1231.     since these also have a unary and binary interpretation which
  1232.     depends on context.
  1233.  
  1234.     In these cases, the compiler interprets the operators as unary
  1235.     operators, and issues a warning to let you know that the usage
  1236.     was ambiguous.  The warning is TADS-357:
  1237.  
  1238.       TADS-357: warning: operator '-' intepreted as unary in list
  1239.  
  1240.     Note that this is a change from the previous version for the '+'
  1241.     and '-' operators.  If your game depends on building lists from
  1242.     calculated numeric constants, you will need to change your code;
  1243.     we don't expect that any games actually depend on the old behavior.
  1244.  
  1245.     If you really do want the operators in these cases interpreted
  1246.     as binary operators, use parentheses:
  1247.  
  1248.        list2 = [(5 -2 -6 -7)]
  1249.  
  1250.     The parentheses tell the compiler that the expression is to be
  1251.     interpreted as a single list element.
  1252.  
  1253.     If you want the unary interpretation, and you want to suppress
  1254.     the warning, use commas between the list elements:
  1255.  
  1256.        list2 = [5, -2, -6, -7]
  1257.  
  1258.     This doesn't change the interpretation, but it does suppress the
  1259.     warning, because it removes the ambiguity:  when the commas are
  1260.     present, there is no way the '-' operators could be interpreted
  1261.     as binary operators.
  1262.  
  1263.     You can suppress the TADS-357 warning if you wish using a new -v
  1264.     suboption.  Specify -v-abin in your compiler options to turn off
  1265.     the warning ("abin" is short for "ambiguous binary operator", which
  1266.     is the meaning of the warning).  You may want to suppress this
  1267.     warning when compiling code written prior to this version of TADS,
  1268.     since the warning is generated in case you wanted the new meaning
  1269.     of the & operator.
  1270.  
  1271.   - A new compiler command-line option has been added:  -C, a toggle
  1272.     option, which turns on and off C-language operator compilation.
  1273.     By default, C operator mode is off (-C-), which makes the compiler
  1274.     use the normal TADS operators.  Specifying -C+ turns on C operator
  1275.     mode; specifying -C- disables C operator mode.
  1276.  
  1277.     When C-language operator mode is in effect, two operators are
  1278.     affected:  the assignment operator becomes '=', and the equality
  1279.     comparison operator becomes '=='.  With normal TADS operator mode
  1280.     in effect, assignment is ':=' and equality is '='.  If you are
  1281.     a C programmer, and you're unhappy with the slight variation in
  1282.     operator notation between TADS and C, you can use -C+ to make TADS
  1283.     behave more like a real language.  Thanks to the #pragma C options
  1284.     (see below), C operator mode has no effect on your choice of
  1285.     header files -- you can use the same old adv.t and other header
  1286.     files unchanged, and still use C-style operators in your code.
  1287.  
  1288.   - A new preprocessor command has been added:  #pragma.  This special
  1289.     directive can be used to specify certain compiler options from
  1290.     within your source code.  Currently, the only #pragma option available
  1291.     is the C operator mode option.  Use #pragma C+ to turn on C operator
  1292.     mode, and #pragma C- to turn it off.
  1293.  
  1294.     The #pragma C+ and #pragma C- settings are local to a particular
  1295.     file.  If a file is included by another file, the #pragma C settings
  1296.     specified in the included file will be in effect only until the end
  1297.     of the included file; the including file's #pragma C settings that
  1298.     were in effect before including the other file will be restored at
  1299.     the end of the included file.  adv.t and std.t now start with a
  1300.     #pragma C- command -- this allows adv.t and std.t to be included
  1301.     from a file with C-style operators (and thus a #pragma C+ or
  1302.     command-line C operator mode setting).  Since the enclosing file's
  1303.     #pragma C option will be restored after the inclusion, files with
  1304.     different operator modes can be freely intermixed with #include, as
  1305.     long as each included file specifies its desired mode with a
  1306.     #pragma C directive.
  1307.  
  1308.   - The precedence of the comparison operators has been changed to
  1309.     be the same as that used by C.  Previously, all of the comparison
  1310.     operators were at the same precedence; starting with this version,
  1311.     == and <> (and thus !=) are at the same level of precedence, and
  1312.     associate left to right as before, but <, >, <=, and >= are one
  1313.     level higher in precedence.  The following type of expression will
  1314.     be affected:
  1315.  
  1316.           a > 1 <> b > 1
  1317.  
  1318.     Previously, this grouped as:
  1319.  
  1320.           (((a > 1) <> b) > 1   // obsolete
  1321.  
  1322.     This now groups as:
  1323.  
  1324.           (a > 1) <> (b > 1)    // current behavior
  1325.  
  1326.     This shouldn't affect any existing code, since the old interpretation
  1327.     should always have resulted in an error (because a truth value, true
  1328.     or nil, can not be compared in magnitude to a number or other type).
  1329.  
  1330.   - Limited conditional compilation and preprocessor text substitution
  1331.     (#define) support has been added to the compiler.  The following
  1332.     preprocessor directives are now available:
  1333.  
  1334.       #define symbol value
  1335.       #undef symbol
  1336.       #ifdef symbol
  1337.       #ifndef symbol
  1338.       #else
  1339.       #endif
  1340.  
  1341.     #define is used to assign a value to a preprocessor symbol.  The
  1342.     "value" is simply text that will be substituted verbatim for the
  1343.     symbol whenever it occurs in your file (other than within quoted
  1344.     strings).  For example:
  1345.  
  1346.       #define TEST say('hello from TEST!')
  1347.  
  1348.       myfunc: function
  1349.       {
  1350.          TEST;
  1351.       }
  1352.  
  1353.     The symbol TEST is replaced with its definition, so the function
  1354.     myfunc() displays "hello from TEST!" when called.
  1355.  
  1356.     Preprocessor symbols defined with #define are in a separate
  1357.     namespace from all other symbols in your program.  Unlike a
  1358.     standard C preprocessor, no arguments are allowed in #define
  1359.     macros.
  1360.  
  1361.     #undef deletes a previously #define'd symbol.  You can #undef
  1362.     the special symbols defined automatically by the compiler if
  1363.     you wish (see below).
  1364.  
  1365.     #ifdef tests to see if a preprocessor symbol is defined.  If it
  1366.     is, the lines following the #ifdef line, and up to the corresponding
  1367.     #else or #endif, are included; otherwise, they are ignored.
  1368.  
  1369.     #ifndef is the opposite of #ifdef:  #ifndef tests to see if the
  1370.     symbol is NOT defined.  If the symbol is undefined, the lines
  1371.     following the #ifndef line up to the corresponding #else or
  1372.     #endif are included; otherwise, they are ignored.
  1373.  
  1374.     #else indicates that the lines between the #else and #endif are
  1375.     to be included if an only if the corresponding #ifdef (or #ifndef)
  1376.     failed.  #else is optional.  At most one #else is allowed per
  1377.     conditional.
  1378.  
  1379.     #endif terminates a conditional block.  Exactly one #endif must appear
  1380.     for each conditional (#ifdef or #ifndef).
  1381.  
  1382.     You can use #ifdef to compile certain parts of your code
  1383.     conditionally.  For example, if you want to include a verb only
  1384.     for your debugging version of a game, but you want to remove it
  1385.     from the final version, you could do something like this:
  1386.  
  1387.       #ifdef __DEBUG
  1388.       magicVerb:  deepverb
  1389.          verb = 'xyzzy'
  1390.          action(actor) =
  1391.          {
  1392.          }
  1393.       ;
  1394.       #endif
  1395.  
  1396.     Note that __DEBUG is especially handy for this sort of thing,
  1397.     because the compiler automatically defines this symbol when
  1398.     debugging (-ds) is turned no (see below).
  1399.  
  1400.   - The compiler automatically defines several preprocessor symbols.
  1401.     These symbols can be used or tested within your code as needed.
  1402.  
  1403.     __TADS_VERSION_MAJOR is defined to a number indicating the major
  1404.     version number of the compiler (in the present system, 2).
  1405.  
  1406.     __TADS_VERSION_MINOR is defined to a number indicating the minor
  1407.     version number (in the present system, 2).
  1408.  
  1409.     __TADS_SYSTEM is defined to a string (single-quoted) identifying
  1410.     the operating system the compiler is running on.  In addition, the
  1411.     same identifier contained in the string is defined as a preprocessor
  1412.     symbol itself (its value is always 1; it is intended that it will
  1413.     be tested with #ifdef, and not otherwise used).  For example, if
  1414.     __TADS_SYSTEM is 'MSDOS', the symbol MSDOS will be defined to 1.
  1415.     If __TADS_SYSTEM is 'Macintosh', the symbol Macintosh will be
  1416.     defined to 1.
  1417.  
  1418.     __DEBUG is defined to 1 if debugging is turned on for this
  1419.     compilation (with the -ds compiler option).  Otherwise, this symbol
  1420.     is not automatically defined.  You can test the existence of __DEBUG
  1421.     with #ifdef to conditionally include code only when you are compiling
  1422.     for debugging.  This might be useful if you want to include certain
  1423.     commands only in the debugging version of your game, and want to
  1424.     remove them when you actually deliver the game to players.
  1425.  
  1426.     If this set of symbols were entered manually with #define statements,
  1427.     the definitions might look like this:
  1428.  
  1429.       #define __TADS_VERSION_MAJOR  2
  1430.       #define __TADS_VERSION_MINOR  2
  1431.       #define __TADS_SYSTEM         'MSDOS'
  1432.       #define MSDOS
  1433.  
  1434.     __DATE__ is defined as a single-quoted string giving the system date
  1435.     when the compilation began, in the format "Jan 01 1980".
  1436.  
  1437.     __TIME__ is defined as a single-quoted string giving the system time
  1438.     when the compilation began, in a 24-hour format, "13:40:50".
  1439.  
  1440.     __FILE__ is defined as a single-quoted string giving the file being
  1441.     scanned at the point where the __FILE__ macro is encountered.  Each
  1442.     time you use __FILE__, it will have the correct value for that point
  1443.     in your source code.
  1444.  
  1445.     __LINE__ is defined as a number giving the line number at the point
  1446.     where the __LINE__ macro is encountered.  Each time you use __LINE__,
  1447.     it will have the correct value for that point in your source code.
  1448.  
  1449.   - The compiler has two new options that give you further control
  1450.     over preprocessor symbols.  The -D option allows you to define
  1451.     a preprocessor symbol from the command line.  For example, to
  1452.     define TEST to 5 from the command line, you could do this:
  1453.  
  1454.       tc -i/tads/include -DTEST=5 mygame.t
  1455.  
  1456.     Note that if you omit the equals sign, the default definition
  1457.     of the symbol will be 1:
  1458.  
  1459.       tc -i/tads/include -DTEST mygame.t
  1460.  
  1461.     This defines TEST to 1.
  1462.  
  1463.     The -U option undefines a predefined symbol.  You can use this to
  1464.     undefine one of the symbols automatically defined by the compiler.
  1465.     You can also use it to undefine a symbol defined in a precompiled
  1466.     header, if you're loading one; -U is applied after the precompiled
  1467.     header is loaded, so it will undefine symbols loaded from the file.
  1468.     For example, to compile for debugging, but leave __DEBUG undefined,
  1469.     you could do this:
  1470.  
  1471.       tc -ds -U__DEBUG mygame.t
  1472.  
  1473.     The -U option is applied after all -D options, so you can also use
  1474.     it to undefine a symbol placed earlier on the command line.  This
  1475.     may be useful if you are using a configuation file (CONFIG.TC)
  1476.     that contains -D options for symbols you sometimes want to undefine.
  1477.  
  1478.   - The compiler has a new preprocessor directive, #error, which allows
  1479.     you to generate your own error during compilation.  If a #error
  1480.     directive is encountered, any text after the #error is displayed
  1481.     as a compiler error; an occurrence of #error is counted as an actual
  1482.     compilation error, so compilation will fail if #error is encountered.
  1483.     For example:
  1484.  
  1485.        #ifndef TEST
  1486.        # error TEST is not defined!
  1487.        #endif
  1488.  
  1489.     If the preprocessor symbol TEST is not defined at the point when
  1490.     this sequence is encountered, the compiler will display an error:
  1491.  
  1492.       mygame.t(181): error TADS-124: TEST is not defined!
  1493.  
  1494.   - The runtime has a new debugging feature that may help you track
  1495.     down problems with word definitions.  You can make the player
  1496.     command parser generate a number of status messages as it analyzes
  1497.     a player's command; these messages provide information on how the
  1498.     parser is interpreting the words in the command.
  1499.  
  1500.     To activate this new debug mode, use the debugTrace function with
  1501.     these arguments:
  1502.  
  1503.        debugTrace(1, true);
  1504.  
  1505.     To turn the debug mode off, call with nil instead of true.  This
  1506.     debugTrace function is always available, even when running under
  1507.     the normal runtime; the function returns no value when called with
  1508.     these arguments.
  1509.  
  1510.   - The built-in function incturn() has been extended to allow you
  1511.     to run a series of turns all at once.  You can now specify a numeric
  1512.     argument to incturn(); the argument gives the number of turns that
  1513.     should pass.  An argument of 1 causes incturn() to behave as usual.
  1514.  
  1515.     When an argument higher than 1 is given to incturn(), the function
  1516.     runs all of the fuses that are set to burn down within the number
  1517.     of turns specified, but not after that number of turns.  Note that
  1518.     the normal incturn() has never actually executed any fuses, but
  1519.     simply burns down all fuses by one more turn.
  1520.  
  1521.     For example, if you call incturn(2), the system will first run
  1522.     any fuses that are set to burn down after 1 turn, then will shorten
  1523.     all remaining fuses by one more turn.
  1524.  
  1525.   - A new built-in function, skipturn(), has been added.  This new
  1526.     function takes a numeric argument specifying the number of turns
  1527.     to skip; it must be at least 1.  skipturn(n) is similar to incturn(n),
  1528.     except that it does not run any of the fuses that burn down during
  1529.     the 'n' turns -- instead, it simply removes them without running
  1530.     them.
  1531.  
  1532.   - A new built-in function allows you to force capitalization off --
  1533.     this function, nocaps(), is the opposite of caps().  If you call
  1534.     caps() then call nocaps(), the next character is lower-case; if
  1535.     you call nocaps() then caps(), the next character is capitalized.
  1536.  
  1537.     Along with nocaps(), the special sequence \v has been added.  Using
  1538.     this sequence in a displayed string is equivalent to calling
  1539.     nocaps(); this sequence is analogous to \^, which is equivalent
  1540.     to calling caps().
  1541.  
  1542.   - A new built-in function has been added to clear the screen:
  1543.     clearscreen(), which takes no arguments and has no return value,
  1544.     simply clears the screen.  This routine may do nothing on some
  1545.     platforms; for example, in -plain mode on DOS, clearscreen() has
  1546.     no effect.
  1547.  
  1548.   - The parser is now capable of disambiguating direct objects before
  1549.     indirect objects.  By default, everything works as it always has --
  1550.     in a two-object command, the indirect object is disambiguated first,
  1551.     and then the direct object is disambiguated in the presence of the
  1552.     known indirect object.
  1553.  
  1554.     It is now possible, however, to specify that the reverse should be
  1555.     done.  To do this, you use a new special flags syntax when defining
  1556.     your verb:
  1557.  
  1558.        tellVerb: deepverb
  1559.           verb = 'tell'
  1560.           desc = "tell"
  1561.           ioAction(aboutPrep) = [disambigDobjFirst] 'TellAbout'
  1562.        ;
  1563.  
  1564.     The new special flags are placed in square brackets between the
  1565.     equals sign and the property template for the verb definition.
  1566.     The flags currently accepted are:
  1567.  
  1568.        disambigDobjFirst
  1569.        disambigIobjFirst
  1570.  
  1571.     Note that disambigIobjFirst is provided for completeness only; it
  1572.     is never needed, because it is the default setting.
  1573.  
  1574.     When the disambigDobjFirst flag is specified, it means that the
  1575.     command should have its direct object disambiguated before its
  1576.     indirect object.
  1577.  
  1578.     When the disambiguation order is reversed, the normal argument
  1579.     lists for verDoTellAbout and verIoTellAbout are interchanged.
  1580.     For our example, the prototypes for the verifier methods become:
  1581.  
  1582.        verDoTellAbout(actor)
  1583.        verIoTellAbout(actor, dobj)
  1584.  
  1585.     Normally, verIoVerb would not receive the direct object as an
  1586.     argument, because the direct object would not be known at the time
  1587.     of the verIoVerb call; and verDoVerb would receive the indirect
  1588.     object as an argument, because it would be known by the time the
  1589.     direct object was being tested.  When the disambiguation order is
  1590.     reversed, however, so are the prototypes to these functions.
  1591.  
  1592.     The actual action method, ioTellAbout(actor, dobj), remains
  1593.     unchanged.  All other methods also remain the same.
  1594.  
  1595.     When the direct object is disambiguated first, the player is not
  1596.     allowed to use multiple direct objects (or multiple indirect objects)
  1597.     in the command.  If the player tries to do so, the new parseError
  1598.     message number 28 is displayed:
  1599.  
  1600.        >tell bob and bill about gun
  1601.        You can't use multiple objects with this command.
  1602.  
  1603.   - Note that a .GAM file format change was required to support the
  1604.     extra information needed for the disambigDobjFirst flag.  The TADS
  1605.     file format is now format "C".  The compiler is still capable of
  1606.     producing formats A or B, in case you need to generate .GAM files
  1607.     that can be played with versions prior to 2.2; however, if you
  1608.     use a format prior to C, you will not be allowed to use the
  1609.     disambigDobjFirst flag (or any other similar flags that may be
  1610.     added in the future).
  1611.  
  1612.   - Two new methods have been added to disambiguate actors.  Previously,
  1613.     the system validated and disambiguated an actor by pretending that
  1614.     you were attempting to take the actor -- takeVerb.validDo and the
  1615.     actor's verDoTake were used to validate and disambiguate the actor,
  1616.     when all you wanted to do was speak to him.  This did not always
  1617.     produce satisfactory results, and in particular did not allow for
  1618.     such situations as talking over a radio to an actor in another room.
  1619.     To provide better control over actor validation and disambiguation,
  1620.     the system for testing actors has been enhanced.
  1621.  
  1622.     First, to validate an actor, the system now uses the method
  1623.     validActor in the actor object itself.  This method takes no
  1624.     arguments; it returns true if the object is valid as an actor in
  1625.     a command, nil otherwise.  This method is called before the verb
  1626.     or any of the objects involved in the sentence are known.  Its
  1627.     function is not to determine whether the actor wants to receive
  1628.     the command, or even if the object can be used as an actor
  1629.     (actorAction is the place to do both of these tests), but rather
  1630.     simply to determine if the object can be addressed by the player
  1631.     at all.  This method should return true if the actor is accessible
  1632.     by voice command (or whatever other means you want to provide for
  1633.     giving commands) to the player.  The default thing.validActor in
  1634.     adv.t returns true if the object is reachable by Me, which provides
  1635.     roughly the same behavior as the old takeVerb-based mechanism.
  1636.  
  1637.     Second, to disambiguate an actor, the new preferredActor method
  1638.     has been added.  This method is called if an actor is ambiguous.
  1639.     As with validActor, it doesn't take any arguments, and it returns
  1640.     true if the object is "preferred" as an actor, nil otherwise.  If
  1641.     exactly one ambiguous object's preferredActor method returns true,
  1642.     the parser will use that object as the actor without further
  1643.     questioning the player; otherwise, the system will ask the player
  1644.     to disambiguate the noun as normal.  In adv.t, movableActor defines
  1645.     preferredActor = true.
  1646.  
  1647.     An example of how these might be used:
  1648.  
  1649.        Sleeping Compartment
  1650.           You are in a sleeping compartment on a moving train.
  1651.        A pair of bunks is along each wall.
  1652.           There is a copper wire here.
  1653.           The train conductor is standing in the doorway, asking for
  1654.        your ticket.
  1655.  
  1656.        >look at conductor
  1657.        Which conductor do you mean, the copper wire, or the train
  1658.        conductor?
  1659.  
  1660.        >copper
  1661.        It's a piece of wire, about a foot long.
  1662.  
  1663.        >conductor, where is ivan?
  1664.        "Your ticket, please," is all the conductor has to say.
  1665.  
  1666.     In this sequence, when the command is addressed to "conductor", the
  1667.     parser matches both the copper wire and the train conductor.  It
  1668.     checks validActor in each of them -- both return true, since both
  1669.     are accessible to the player.  (As described above, even though the
  1670.     copper wire couldn't possibly be an actor, it is valid as an actor
  1671.     at this point -- it's not until its actorAction that we will decide
  1672.     that there's no point in talking to it.)
  1673.  
  1674.     So, the parser has an ambiguous actor.  The parser tries to
  1675.     disambiguate the actor by testing preferredActor in each object.
  1676.     The copper wire's preferredActor returns nil; the train conductor's,
  1677.     however, returns true, because the conductor is a movableActor
  1678.     object.  The parser now has only one object, and thus doesn't
  1679.     need to ask the player for further information.
  1680.  
  1681.     For compatibility with games compiled with previous versions of
  1682.     adv.t, the parser will continue to use the old mechanism (involving
  1683.     the takeVerb) if validActor is not defined in your game.  Each time
  1684.     an actor is used, the parser checks to see if the first object in
  1685.     the list of possible actor objects has a validActor method defined;
  1686.     if not, the parser uses the old mechanism.  If you use the new adv.t,
  1687.     all objects will at least inherit a validActor method (from thing),
  1688.     so testing for the presence of this method in any object lets the
  1689.     parser determine if the new mechanism can be used with the game.
  1690.  
  1691.   - A new parseError message has been added:  number 27, whose default
  1692.     text is "You can't repeat that command."  This message is displayed
  1693.     when the player types AGAIN, but the parser can't repeat the command;
  1694.     this is the case if one of the objects involved in the command is
  1695.     no longer accessible.
  1696.  
  1697.   - A new parseError message has been added, related to validActor
  1698.     (see above).  This new message, number 31, is used when none of
  1699.     the objects matching the vocabulary for an actor in a player's
  1700.     command can be used as an actor.  The default text of this message
  1701.     is "You can't talk to that."  For example, if there is no object
  1702.     matching the vocabulary "guard" whose validActor method returns
  1703.     true, but an object named "guard" is visible to the player, the
  1704.     message is used:
  1705.  
  1706.       Security Room
  1707.           You are inside a small cubicle.  A thick, laser-proof
  1708.       (as you now know from your ill-fated attempt) glass door
  1709.       (closed) is to the north.  Through the door you can see
  1710.       a guard standing watch.
  1711.  
  1712.       >guard, open door
  1713.       You can't talk to that.
  1714.  
  1715.     This message is used for actors in place of the standard cantReach
  1716.     processing done for direct and indirect objects under these conditions.
  1717.  
  1718.   - A new parseError code, number 29, has been added.  The default
  1719.     message is "I think you left something out after 'any of'", and
  1720.     is used when the player uses "any of" in a sentence, but doesn't
  1721.     follow it with anything.
  1722.  
  1723.   - Using the same word as both a plural and a noun works much better
  1724.     now.  The parser will first attempt to use such a word as a plural;
  1725.     if no objects match the plural usage, the parser will try to use
  1726.     the word as a noun instead.
  1727.  
  1728.   - "of" can now be used as a preposition.  In previous versions of
  1729.     the run-time, "of" was exclusively a special word that was embedded
  1730.     in noun phrases (such as "pile of paper").  The runtime will still
  1731.     allow "of" to be used in noun phrases as before, but it also will
  1732.     treat "of" as an ordinary word when, based on the context, it does
  1733.     not appear to be part of a noun phrase.
  1734.  
  1735.     The parser will still attempt to treat "of" as part of a noun
  1736.     phrase whenever it matches an object.  For example, if you have
  1737.     an object with nouns matching "pile of paper", then the following
  1738.     interpretations will apply:
  1739.  
  1740.         accuse bob of murder   ->  dobj = bob, iobj = murder, prep = of
  1741.         accuse pile of paper   ->  dobj = pile of paper
  1742.  
  1743.     Note that ofPrep, defining "of" as a preposition, has been added
  1744.     to adv.t.
  1745.  
  1746.   - All of the system verbs that use "abort" have been modified
  1747.     slightly in adv.t to make it easier to augment their behavior
  1748.     with the 'modify' statement.  All of the processing other than
  1749.     the "abort" has been moved out of the doVerb (or action) method
  1750.     in each case, and put into a new method.  For example, saveVerb's
  1751.     action routine now looks like this:
  1752.  
  1753.         action( actor ) =
  1754.         {
  1755.         self.saveGame(actor);
  1756.         abort;
  1757.     }
  1758.  
  1759.     The new method saveVerb.saveGame(actor) now performs all of the
  1760.     processing that the action(actor) method previously performed.
  1761.  
  1762.     The benefit of this change is that you can now modify the
  1763.     saveGame(actor) method, and inherit the original behavior,
  1764.     without having to worry about an "abort" interfering with the
  1765.     order of operations.  For example:
  1766.  
  1767.         modify restoreVerb
  1768.             restoreGame(actor) =
  1769.             {
  1770.                 // restore the game as usual - check for success
  1771.                 if (inherited.restoreGame(actor))
  1772.                 {
  1773.                     // re-randomize the puzzle
  1774.             "The carnival hawker flashes a mischevious
  1775.             smile at you.  \"There's no use trying to
  1776.             guess the answer,\" he says.  \"I changed
  1777.             around the shells while you were busy
  1778.             restoring!\"";
  1779.             puzzle.answer := rand(100);
  1780.                 }
  1781.             }
  1782.         ;
  1783.  
  1784.  
  1785.   - The format mask fmtMe has been added.  You can now use %me% in
  1786.     messages to refer to the actor.  For basicMe, fmtMe is set to
  1787.     the message "me"; for other actors, it is set to the actor's
  1788.     thedesc.  In adv.t, thing.ldesc has been changed to use %me%:
  1789.     "It looks like an ordinary <<sdesc>> to %me%."  This makes the
  1790.     default sentence somewhat more adaptable if you ask another
  1791.     actor to describe something:
  1792.  
  1793.         >guard, look at the card
  1794.         It looks like an ordinary card to the guard.
  1795.  
  1796.   - AGAIN, WAIT, and SLEEP are now darkVerb's in adv.t.
  1797.  
  1798.   - A new verb, breakVerb, has been added to adv.t.  The vocabulary
  1799.     words for this verb are 'break', 'destroy', and 'ruin', and it
  1800.     provides a single-object command "break <direct-object>".  The
  1801.     thing class has been adjusted so that verDoBreak(actor) validates
  1802.     breaking any object, but doBreak(actor) simply displays "You'll have
  1803.     to tell me how to do that."  If you want to make a breakable object,
  1804.     simply override doBreak(actor) so that it breaks the object (you may
  1805.     also want to override verDoBreak(actor) so that it doesn't allow a
  1806.     broken object to be broken again).
  1807.  
  1808.   - "there" has been added a synonym for "it" in the specialWords list
  1809.     in adv.t.  This allows sentences like this:
  1810.  
  1811.         >get box.  put ball in there.
  1812.  
  1813.   - lightsource now has a doTurnnon method in adv.t.  This method will
  1814.     show the room's description if the room becomes lit as a result
  1815.     of turning on the lightsource.  Note that lightsource, by default,
  1816.     has no verDoTurnon, so you can't turn a generic light source on
  1817.     and off.  However, if you add switchItem to the superclass list of
  1818.     a lightsource object, you will have a light source that you can
  1819.     turn on and off, and which will have this new behavior.  Note that
  1820.     you should put lightsource in the superclass list prior to
  1821.     switchItem, so that lightsource.doTurnon overrides switchItem.doTurnon:
  1822.  
  1823.         flashlight:  lightsource, switchItem
  1824.             sdesc = "flashlight"
  1825.             noun = 'flashlight' 'light'
  1826.             adjective = 'flash'
  1827.             location = tunnel
  1828.         ;
  1829.  
  1830.   - verIoGiveTo and ioGiveTo have been added to movableActor in adv.t.
  1831.     verIoGiveTo rejects the command if the actor is the same as the
  1832.     indirect object, otherwise the command is accepted.  ioGiveTo
  1833.     always rejects the offer.  In addition, ioGiveTo has been added
  1834.     to basicMe; the method always accepts anything from another actor,
  1835.     because this method will only be called in response to commands
  1836.     such as:
  1837.  
  1838.         >guard, give me the key
  1839.  
  1840.   - A small problem with thing.isVisible in adv.t has been fixed.  If
  1841.     the vantage is inside the object, and the object's contents are
  1842.     visible, isVisible returns true.  This is is needed in certain
  1843.     situations involving nested rooms.
  1844.  
  1845.   - moveableActor.travelTo(room) in adv.t has been corrected so
  1846.     that it does nothing when room = nil, which is the case when the
  1847.     actor can't travel in the desired direction.  Previously, the
  1848.     "noexit" message would be displayed, but then the actor would
  1849.     be moved into a nil location.
  1850.  
  1851.   - moveableActor now has a roomCheck method in adv.t.  The method
  1852.     is the same as basicMe's roomCheck method; its omission in
  1853.     previous versions was an oversight.
  1854.  
  1855.   - The showcontcont function in adv.t has been corrected so that
  1856.     the isqsurface flag is checked correctly.
  1857.  
  1858.   - A new class, seethruItem, has been added to adv.t.  This class is
  1859.     intended for objects such as windows or magnifying glasses which
  1860.     the player can look through.  Each object of this class should
  1861.     define an appropriate thrudesc method, which displays what the
  1862.     player sees when looking through this object.
  1863.  
  1864.     Note that a seethruItem is not the same as a transparentItem.
  1865.     The class transparentItem is intended for objects, such as glass
  1866.     bottles, whose contents are visible, whereas seethruItem is intended
  1867.     for objects that are not containers but which the player can look
  1868.     through.
  1869.  
  1870.   - The compiler now sets an error code on exit.  If you are using
  1871.     a MAKE utility or other program-building tool, you can use the
  1872.     exit code.  On success, the compiler uses exit code 0; if any
  1873.     errors occurred, a non-zero exit code is used.
  1874.  
  1875.   - The compiler no longer creates a .GAM file if errors occurred
  1876.     during compilation.  If a .GAM file of the same name exists
  1877.     prior to a compilation, and errors occur, the original .GAM
  1878.     file is unaffected (it is not deleted or overwritten).  Although
  1879.     the compiler previously produced a .GAM file even when an error
  1880.     occurred, this .GAM file was not generally usable; to avoid
  1881.     confusion, the compiler no longer produces a .GAM file at all
  1882.     when an error occurs.
  1883.  
  1884.   - The compiler performs more checking for invalid -m parameters.
  1885.     When -m parameters are entered that exceed the compiler's internal
  1886.     limits, it will report an error and abort the compilation.  The
  1887.     affected options are -mp, -ml, and -ms.  The runtime similarly
  1888.     checks its parameters more carefully now.
  1889.  
  1890.   - The DOS runtime no longer displays anything on the status line at
  1891.     startup.  It initializes both the left portion (which normally is
  1892.     used to display the location) and the right portion (which is
  1893.     normally used to display the score and turn count) to empty
  1894.     strings.  To ensure that a score is properly displayed at the
  1895.     start of the first turn, we added a call to scoreStatus(0, 0) in
  1896.     the "init" function defined in std.t.
  1897.  
  1898.   - The DOS runtime now has a plain ASCII mode.  In this mode, the
  1899.     runtime uses only DOS character input and output functions,
  1900.     performs no highlighting or cursor positioning, and does not
  1901.     display a status line.  Command editing and screen scrollback
  1902.     are also disabled (although normal DOS keyboard editing can be
  1903.     used, and any loaded command editor, such as DOSKEY, will be
  1904.     active).  This mode is intended for people with a special need
  1905.     to use direct DOS character I/O, such as persons using a voice
  1906.     synthesizer.  To invoke this mode, specify -plain in the runtime
  1907.     command options:
  1908.  
  1909.           tr -plain mygame
  1910.  
  1911.     Note that .EXE files produced by MAKETRX can be used in this
  1912.     manner as well; simply specify -plain with the game program:
  1913.  
  1914.           deep -plain
  1915.  
  1916.   - The DOS runtime now uses the control-left-arrow and
  1917.     control-right-arrow to move the cursor left and right by one
  1918.     word in the command editor.  This behavior is consistent with
  1919.     most other DOS command editors.
  1920.  
  1921.   - $$ABEND can now be used after a question from the parser, such
  1922.     as during disambiguation and when OOPS is permitted.
  1923.  
  1924.   - The runtime handles hyphenation better.  Multiple hyphens will
  1925.     no longer be split across lines -- so if you use two hyphens
  1926.     together for a dash, both hyphens will always be grouped on one
  1927.     line.  Furthermore, the runtime formatter will never put a dash
  1928.     at the very start of a line; if a line must be split at a dash,
  1929.     the formatter will put the dash at the end of the line, then
  1930.     break the line, and will back up and split at the previous word
  1931.     if necessary.
  1932.  
  1933.   - The runtime will now properly convert "\" sequences in askfile()
  1934.     prompts properly.  If you use a \n, \t, \', \", or \\ sequence
  1935.     in a prompt to askfile(), the sequence will be displayed as the
  1936.     appropriate character.  (For the DOS runtime, this only matters
  1937.     in -plain mode, because the DOS file selector in the normal full-
  1938.     screen mode doesn't use the prompt string.)
  1939.  
  1940.   - The DOS runtime's file selector dialog incorrectly interpreted
  1941.     the Alt keys for disks in the last version -- Alt-B selected the A
  1942.     drive, Alt-C selected the B drive, and so forth.  This has been
  1943.     corrected.
  1944.  
  1945.   - The MAKETRX command now takes an additional argument that lets
  1946.     you specify the run-time command options that should be used when
  1947.     the game is executed.  MAKETRX still accepts the original command
  1948.     formats; using one of the old-style command formats will not bind
  1949.     any command options into the resulting .EXE file.
  1950.  
  1951.     To specify command options for your game executable, you must
  1952.     first create a file.  Use the same format as CONFIG.TR -- simply
  1953.     enter your options into the file as you would on the TR command
  1954.     line; separate options by newlines or spaces.  For example, to
  1955.     specify a minimal cache size and a swap file of SWAP.DAT, you
  1956.     could make your CONFIG.TR file look like this:
  1957.  
  1958.         -m0 -tf swap.dat
  1959.  
  1960.     Once you've created a file with your command options, specify
  1961.     that file to MAKETRX by using it as the first parameter on the
  1962.     command line, prefixed with an "at" sign (@):
  1963.  
  1964.         maketrx @config.tr mygame
  1965.  
  1966.     The @config option can be used with any of the original command
  1967.     formats for MAKETRX.  Once the config file is bound into your
  1968.     executable, its options will be used every time a player runs
  1969.     your game's .EXE file.  Note that you may want to avoid specifying
  1970.     anything specific to your system, such as drives or directories,
  1971.     since that may prevent the game from working properly on someone
  1972.     else's system.
  1973.  
  1974.   - The new sentence parsing for the form VERB PREP IOBJ DOBJ
  1975.     (introduced in 2.1.1) causes a subtle problem:  if you create
  1976.     an object with an adjective that is also a preposition, the
  1977.     system attempts to interpret sentences with a single-word verb
  1978.     that refers to the object as VERB PREP IOBJ.  The result is
  1979.     this:
  1980.  
  1981.        >push off button
  1982.        What do you want to push?
  1983.  
  1984.     This is because the parser is interpreting the sentence as
  1985.     "push something off button", and needs to know the "something".
  1986.     This problem has been corrected.  Now, the parser will check this
  1987.     type of case to see if the preposition can also be used as an
  1988.     adjective, and if so, checks to see if a noun (possibly preceded
  1989.     by one or more adjectives) follows; if this test is met, the word
  1990.     will be interpreted as an adjective, as it should be.
  1991.  
  1992.   - The parser now correctly distinguishes between cases involving
  1993.     a word that is defined as both a preposition and an adjective.
  1994.     The parser previously did not accept sentences such as this:
  1995.  
  1996.       >enter south wall
  1997.  
  1998.     when 'south' was defined as an adjective.  Because 'south' was
  1999.     also defined as a preposition (in adv.t), the parser attempted
  2000.     to interpret this sentence as though 'enter south' were a verb
  2001.     (in the same manner as 'pick up' or 'put down').  The parser
  2002.     now checks to make sure that 'enter south' is a valid combination
  2003.     verb; if it's not, and 'south' is also defined as another part of
  2004.     speech, the parser assumes that 'enter' is the verb, and treats
  2005.     'south' as an adjective.
  2006.  
  2007.   - The parser previously asked to disambiguate a direct object twice
  2008.     if askio(prep) was used.  For example:
  2009.  
  2010.        >unlock door
  2011.        Which door do you mean, the large door, or the small door?
  2012.  
  2013.        >large
  2014.        What do you want to unlock it with?
  2015.  
  2016.        >key
  2017.        Which key do you mean, the silver key, or the gold key?
  2018.  
  2019.        >gold
  2020.        Which door do you mean, the large door, or the small door?
  2021.  
  2022.        >large
  2023.        The door unlocks with a satisfying click.
  2024.  
  2025.     This has been corrected -- the parser now only asks once about
  2026.     the door.
  2027.  
  2028.   - The parser did not previously accept a word during disambiguation
  2029.     if the word was defined as both a noun and an adjective.  For
  2030.     example, if you've defined objects "violet paper", "violet banana",
  2031.     and "paper towel", and the parser asked you this:
  2032.  
  2033.        >x violet
  2034.        Which violet do you mean, the violet paper, or the violet banana?
  2035.  
  2036.     then you couldn't respond with "paper".  This has been corrected.
  2037.  
  2038.   - The inputkey() function now clears the "more" line counter.  So,
  2039.     when inputkey() is called, a "more" prompt will not show up until
  2040.     another screenful of text has been displayed.
  2041.  
  2042.   - "local" statements that occur out of context (i.e., as other than
  2043.     the first statements after an open brace) now generate better
  2044.     diagnostics.
  2045.  
  2046.   - Dividing by zero is now flagged as a run-time error.
  2047.  
  2048.   - A problem involving the embedded string << >> notation has been
  2049.     corrected.  Under certain circumstances, if one expression used
  2050.     in an embedded string invoked another string with an embedded
  2051.     expression, an error occurred (usually "invalid type for built-in
  2052.     function").  This should no longer occur.
  2053.  
  2054.   - The system did not properly handle lists containing function
  2055.     pointers.  This has been corrected.
  2056.  
  2057.   - A problem involving pre-compiled headers and 'modify' has been
  2058.     corrected.  Several people have encountered problems that generally
  2059.     were manifested as "assert" failures in mcm.c (the cache manager)
  2060.     when using 'modify' and pre-compiled headers; these should no
  2061.     longer occur.
  2062.  
  2063.   - An internal cache corruption occurred under certain obscure
  2064.     circumstances involving 'modify'.  This has been corrected.
  2065.  
  2066.   - A note on roomCheck:  if you return nil from roomCheck, fuses
  2067.     and daemons are NOT run; in this sense, returning nil from roomCheck
  2068.     is equivalent to using abort in other methods.  (This is not a
  2069.     change -- it's always worked this way -- but this behavior is
  2070.     not mentioned in the TADS Author's Manual.)
  2071.  
  2072.   - A note on using << >> embedded strings:  If you put a newline
  2073.     immediately before the << of an embedded string, any spaces between
  2074.     the last non-space character preceding the << and the << will be
  2075.     lost.  If you want a space before the <<, do not put it on a new
  2076.     line.  Instead, you can put it at the end of the line, and put
  2077.     the embedded expression itself on the next line.  For example:
  2078.  
  2079.         embeddedString = "embedded string"
  2080.         sdesc = "This is a message with an
  2081.                  <<self.embeddedString>>!"     // wrong
  2082.  
  2083.     This will display as follows:
  2084.  
  2085.         This is a message with anembedded string!
  2086.  
  2087.     If you intend a space to precede the embedded string, you should
  2088.     write this as follows:
  2089.  
  2090.         sdesc = "This is a message with an <<
  2091.                 self.embeddedString>>!";      // right
  2092.  
  2093.     (This is not a change, but simply a note for game developers who
  2094.     have encountered this problem.)
  2095.  
  2096.  
  2097. 2.1.2  11/22/93  enhancements, bug fixes
  2098.  
  2099.   - You can now detect when the player uses multiple direct objects
  2100.     with a verb, and reject such commands.  Whenever the player uses
  2101.     multiple direct objects with a command (or uses "all", even if it
  2102.     results in a single object being used), the parser calls the
  2103.     verb object's rejectMultiDobj(prep) method.  If you don't wish to
  2104.     take any special action for multiple direct objects used with a
  2105.     particular verb, simply return nil from this method (or don't
  2106.     define the method at all for the verb).  If you want to prevent
  2107.     multiple direct objects from being used, however, you should display
  2108.     an appropriate message, and return true.  The parser will skip the
  2109.     command entirely.  Note that the parser doesn't display any additional
  2110.     message when rejectMultiDobj(prep) returns true; the method should
  2111.     display whatever message is desired.  The "prep" parameter is the
  2112.     preposition object used with the command; it will be nil if no
  2113.     indirect object is present.  An example:
  2114.  
  2115.         modify inspectVerb
  2116.             rejectMultiDobj(prep) =
  2117.             {
  2118.                 "You can only look at one thing at a time.";
  2119.                 return true;
  2120.             }
  2121.  
  2122.     The verb's rejectMultiDobj(prep) method is called immediately
  2123.     before the actor's actorAction method.  Note that the parser will
  2124.     continue processing any remaining commands on the line, and will
  2125.     then run daemons and fuses as normal, even if rejectMultiDobj(prep)
  2126.     returns true; if you want to stop the current turn altogether, use
  2127.     abort.
  2128.  
  2129.   - The player command parser now gives you greater control over object
  2130.     validation error reporting.  In previous versions, if an object was
  2131.     visible but did not pass the validIo/validDo test, the parser called
  2132.     the object's cantReach method to report the error (see the note below
  2133.     about an additional change to object.cantReach processing).
  2134.  
  2135.     Now, however, the parser will call verb.cantReach instead, if the
  2136.     command's deepverb object defines (or inherits) a cantReach method.
  2137.     If the verb does not have a cantReach method at all, the parser
  2138.     will use the old behavior instead.  The new cantReach method should
  2139.     be defined as follows:
  2140.  
  2141.        myVerb: deepverb
  2142.            verb = 'whatever'
  2143.            cantReach(actor, dolist, iolist, prep) =
  2144.            {
  2145.                // your code here
  2146.            }
  2147.        ;
  2148.  
  2149.     This method doesn't return a value; it simply displays the appropriate
  2150.     message explaining why the object can't be used with the command.
  2151.     verb.cantReach is used only when the objects are visible (that is,
  2152.     object.isVisible(actor) returned true for each object in the list).
  2153.  
  2154.     Only one of dolist or iolist will be non-nil.  If the direct object
  2155.     of the command refers to one or more objects that are visible but
  2156.     can't be used (according to validDo), dolist will be a list of all
  2157.     such objects, and iolist will be nil.  Otherwise, iolist will be a
  2158.     list of such objects used for the indirect object, and dolist will
  2159.     be nil.
  2160.  
  2161.     adv.t has not been changed to use verb.cantReach.  This change has
  2162.     been made to provide finer control for game authors implementing
  2163.     their own verbs and object validation procedures.
  2164.  
  2165.   - The player command parser had an odd quirk when ambiguous nouns
  2166.     were used with transparent items.  If the player used a command
  2167.     containing a noun that referred to multiple objects that were
  2168.     visible but were not valid for the verb (for example:  "take trophy"
  2169.     in a room containing a closed glass trophy case containing a bowling
  2170.     trophy and a tennis trophy), the parser asked the normal disambiguation
  2171.     question.  This was not really necessary, because the parser already
  2172.     knew that the objects were invalid.  This has been changed; the parser
  2173.     now simply uses the cantReach message for *each* object that is
  2174.     visible and matches the vocabulary, using the usual multiple-word
  2175.     format:
  2176.         bowling trophy:  You'll have to open the glass case first.
  2177.         tennis trophy:  You'll have to open the glass case first.
  2178.  
  2179.     This new behavior should have no effect on your game code.  Note
  2180.     that it is entirely irrelevant if you use the new verb.cantReach
  2181.     feature described above.
  2182.  
  2183.   - The compiler sports a new case sensitivity option.  By default,
  2184.     the compiler is case-sensitive, as it has been in past versions.
  2185.     However, the new toggle option allows you to change this.  Specify
  2186.     -case- to turn off case sensitivity (the default is -case+).  Note
  2187.     that this is a toggle option, so simply using -case will reverse
  2188.     the current case sensitivity (which is useful if you use a CONFIG.TC
  2189.     file that sets a non-default case option).  When case sensitivity
  2190.     is turned off, the compiler will treat upper- and lower-case letters
  2191.     in symbols (names of objects, properties, functions, and local
  2192.     variables) as equivalent.  Hence, foodItem = fooditem = FoodItem,
  2193.     and so on.
  2194.  
  2195.     If you create a pre-compiled header with -w, any compilation which
  2196.     reads that binary header with -l will use the same case sensitivity
  2197.     as was in effect when the header was pre-compiled.  The -case option
  2198.     is ignored when a pre-compiled header is loaded.  Likewise, the
  2199.     debugger uses the same case sensitivity that was in effect when the
  2200.     game being debugged was compiled.
  2201.  
  2202.   - The debugger's command set is no longer case-sensitive (hence,
  2203.     BP = Bp = bP = bp).
  2204.  
  2205.   - adv.t has a new darkVerb class.  This is a type of deepVerb that
  2206.     can be used in the dark.  The darkroom class has been changed to
  2207.     accept any verb of class darkVerb in its roomAction and roomCheck
  2208.     methods.  The travel verbs and system verbs have all been made
  2209.     darkVerb objects, so darkroom only needs to check the single
  2210.     verb type.
  2211.  
  2212.     In a related change, turnOnVerb and dropVerb have been changed to
  2213.     be darkVerb objects, allowing the player to turn on an object or
  2214.     drop it in the dark.  The verDoTurnon method in switchItem has
  2215.     been changed so that it checks to see if the player is in a dark
  2216.     room; if so, the item can only be turned on if the player is already
  2217.     carrying the object.  This allows the player to turn on a light
  2218.     source that's already being carried, but doesn't allow the player
  2219.     to pick up a light source in a dark room.
  2220.  
  2221.   - The compiler issues a new warning message (TADS-452) if you
  2222.     use the same verb with two deepverb objects.  The parser can only
  2223.     choose a single deepverb object for any verb typed by the player,
  2224.     so you should never define the same 'verb' vocabulary word in more
  2225.     than one deepverb object.  In past versions, the compiler did not
  2226.     flag this as a warning.
  2227.  
  2228.   - Several improvements have been made for numbers in player
  2229.     commands.  First, multiple numbers are now allowed in a single
  2230.     commands; for example, the player can now say "press 1, 2, 3,
  2231.     4 on keypad," and the numbers are set in numObj.value, one by
  2232.     one.  Second, the sdesc, adesc, and thedesc properties of
  2233.     basicNumObj have been improved to show the number's value.
  2234.  
  2235.   - Similar improvements to those for numbers have been made for
  2236.     strings.  Multiple strings are now allowed in a single command,
  2237.     and the basicStrObj properties sdesc, adesc, and thedesc have
  2238.     been improved to show the string's value.
  2239.  
  2240.   - specialWords has been enhanced.  First, in past versions, if a
  2241.     game contained multiple specialWords statements, the word lists
  2242.     were additive -- all specialWords lists were used in the game.
  2243.     This has been changed so that each specialWords statement replaces
  2244.     any previous list in effect.  However, you now can explicitly add
  2245.     to the specialWords list, without removing any of the previously
  2246.     defined words, by using "modify specialWords".  When you use
  2247.     'modify', you can use nil in any word slot if you do not wish
  2248.     to add any words for that slot.  Finally, you can use "replace
  2249.     specialWords" to make the replacement explicit; this is the default
  2250.     if neither 'modify' nor 'replace' is specified, but the compiler
  2251.     will now issue a warning (which is harmless) if you use specialWords
  2252.     without 'replace' or 'modify' and a previous specialWords list is
  2253.     already in effect.
  2254.  
  2255.   - The words "one" and "ones" (or their equivalent for your game,
  2256.     if you've changed them with specialWords) are no longer considered
  2257.     reserved words within normal commands.  This allows you to use
  2258.     objects such as a "one dollar bill"; previous versions rejected
  2259.     player commands containing "one" or "ones".  These words are now
  2260.     considered special only during the parsing of a response to a
  2261.     disambiguation question, when they can be used in place of a
  2262.     noun ("the red one" can be used in answer to "Which book do you
  2263.     mean...").
  2264.  
  2265.   - The hider class has been changed so that 'it' or 'them' (as
  2266.     appropriate) are set to the object or objects found when
  2267.     searching the hider.
  2268.  
  2269.   - The verDoPutIn and verDoPutOn messages in thing and surface
  2270.     (respectively) have been improved for the somewhat obscure case
  2271.     of attempted circular containment - that is, putting an object
  2272.     into a container, when the container is already in the first object
  2273.     (either directly or by virtue of being inside another object which
  2274.     is inside the first object, or inside an object which is inside an
  2275.     object which is inside the first object, and so on).  The new
  2276.     method thing.circularMessage(iobj) is called in these cases to
  2277.     display an appropriate message; the default implementation of this
  2278.     method displays the complete list of containers of the direct
  2279.     object out to the indirect object.  For example, if you have a
  2280.     crate which contains a box, and you try to "put crate in box",
  2281.     the message is "You can't put the crate in the box, because
  2282.     the box is already in the crate."
  2283.  
  2284.   - The default doTake method has been changed to include the weight
  2285.     of any contents of the item being taken, in addition to the item
  2286.     itself, to determine if the actor's inventory is too heavy.
  2287.     The old doTake method only included the weight of the object
  2288.     being taken, not counting its contents.
  2289.  
  2290.   - The Actor class has been changed to add a travelTo method.  You
  2291.     can now move any actor (Me included) with travelTo(destination).
  2292.     The default Actor.travelTo method moves the actor; it announces
  2293.     the departure of the actor if the actor was in the same location as
  2294.     Me before leaving (and the location is lit); and it announces the
  2295.     arrival of the actor if the actor is moving into the same location
  2296.     as the player (and the location is lit).  The departure message
  2297.     is generated with a call to self.sayLeaving, and the arrival
  2298.     message is generated with self.sayArriving.  The default versions
  2299.     of these methods simply display "Thedesc leaves the area" and
  2300.     "Thedesc enters the area", respectively; you can override these
  2301.     methods if a more specific message is desired.
  2302.  
  2303.   - When modifying a class object with 'modify', the modified object
  2304.     was not a class unless the 'class' keyword was included with the
  2305.     'modify' statement ("modify class foo" rather than "modify foo").
  2306.     This has been corrected; a modified class is still a class.
  2307.  
  2308.   - outhide(true) now returns a status indicator, which is a value that
  2309.     can be used in a subsequent call to outhide() to return output
  2310.     hiding to the state it was in before the outhide(true).  This
  2311.     allows you to nest text hiding.  When you use the nested form
  2312.     (which you do simply by using the return value of outhide(true) as
  2313.     the parameter - in place of nil - to the subsequent call to outhide()),
  2314.     the value returned by the second outhide() indicates whether any
  2315.     text output occurred ONLY BETWEEN THE NESTED CALLS.  For example:
  2316.     
  2317.      old_stat1 := outhide(true);
  2318.      "This is some hidden text.";
  2319.      old_stat2 := outhide(true);
  2320.      // write no text here
  2321.      new_stat2 := outhide(old_stat2);
  2322.      new_stat1 := outhide(old_stat1);
  2323.  
  2324.     Because outhide(old_stat2) indicates whether any output occurred
  2325.     during the NESTED outhide(true), new_stat2 = nil.  However, new_stat1
  2326.     = true, since output occurred after the first outhide(true).  Consider
  2327.     another sequence:
  2328.  
  2329.      old_stat1 := outhide(true);
  2330.      // write no text here
  2331.      old_stat2 := outhide(true);
  2332.      "This is some hidden text.";
  2333.      new_stat2 := outhide(old_stat2);
  2334.      new_stat1 := outhide(old_stat1);
  2335.  
  2336.     In this case, both new_stat1 and new_stat2 will be true, because
  2337.     hidden output occurred within both nested sections.
  2338.  
  2339.     The general form of a nested hidden output section looks like this:
  2340.  
  2341.          {
  2342.             local original_hide_stat;
  2343.         local nested_stat;
  2344.  
  2345.             hide_stat := outhide(true);
  2346.             // do whatever you want to do while output is hidden
  2347.         nested_stat := outhide(original_hide_stat);
  2348.      }
  2349.  
  2350.     Now nested_stat will indicate whether any output occurred during
  2351.     the nested outhide() - that is, between the outhide(true) and
  2352.     the outhide(original_hide_stat).  In addition, output hiding will
  2353.     be returned to the same state it was in prior to the original
  2354.     outhide(true).
  2355.  
  2356.   - The random number generator has been improved.  Many people have
  2357.     complained about the many undesirable properties of the old
  2358.     generator, especially when small upper limits were used.  The
  2359.     interface to the new random number generator is the same as
  2360.     before - call rand(upper_limit), which will return a uniformly
  2361.     distributed random number from 1 to upper_limit, inclusive.
  2362.  
  2363.     Note that the old random number generator will still be used if
  2364.     you don't call randomize().  This allows test scripts (which require
  2365.     a fixed sequence of random numbers in order to be repeatable) that
  2366.     were written with older versions to continue to operate unchanged.
  2367.     If you want numbers from the improved generator, be sure to call
  2368.     randomize().
  2369.  
  2370.   - When 'modify' was used on an object, the compiler sometimes did
  2371.     not correctly apply the original object's vocabulary and location
  2372.     to the new object.  This has been corrected.
  2373.  
  2374.   - restore() and undo() have been changed so that they always cancel
  2375.     all pending commands on the command line.  In the past, if the
  2376.     player typed several commands, and something happened (such as
  2377.     the player character dying) during one of the commands that led to
  2378.     an undo() or restore(), the remaining commands were still
  2379.     executed.  This has been fixed.
  2380.  
  2381.   - If you explicitly set an object's location to nil in its object
  2382.     definition, and the object inherited a location from a superclass,
  2383.     the system incorrectly placed the object in the contents list of
  2384.     the object named in the location inherited from the object's
  2385.     superclass.  This has been corrected.
  2386.  
  2387.   - "abort" can now be used within a daemon or fuse, and the
  2388.     expected behavior will occur.  In the past, "abort" within
  2389.     a fuse (or daemon) merely exited from the current fuse,
  2390.     but the remaining fuses and daemons were still executed.
  2391.     Now, "abort" will cause the entire turn to end; no more
  2392.     fuses or daemons will be executed on the current turn.
  2393.  
  2394.  
  2395. 2.1.1  09/09/93  enhancements
  2396.  
  2397.   - You can now access objwords(1) while deciding whether to use a
  2398.     default direct object in doDefault.  This is useful mostly if
  2399.     you want to prevent players from being able to use "all" with
  2400.     certain verbs, but still want to generate a default direct object
  2401.     for the verbs.  To do this, you can detect when objwords(1) = ['A']
  2402.     ('A' is the parser's internal code for "all", which saves you the
  2403.     trouble of checking for "everything" and shorter abbreviations as
  2404.     well as "all"):
  2405.  
  2406.       doDefault(actor, prep, iobj) =
  2407.       {
  2408.           if (objwords(1) = ['A'])
  2409.           {
  2410.               global.allMessage := 'You can\'t use "all" with this verb.';
  2411.           return [];
  2412.  
  2413.       /* your normal default object code goes here */
  2414.       }
  2415.  
  2416.     If you wish, you can also suppress the default message that the
  2417.     parser will generate ("I don't see what you're referring to").
  2418.     To do this, you'll have to write your own parseError() function
  2419.     and detect when an "all" violation has occurred (cleverly using the
  2420.     global.allMessage, which we set above for this purpose):
  2421.  
  2422.       parseError: function(str, num)
  2423.       {
  2424.           // if there's an allMessage waiting, use it instead of the default
  2425.           if (global.allMessage <> nil)
  2426.       {
  2427.           local r;
  2428.  
  2429.           r := global.allMessage;
  2430.           global.allMessage := nil;
  2431.           return r;
  2432.       }
  2433.       else
  2434.           return nil;
  2435.       }
  2436.     
  2437.   - The compiler's error message format has been changed slightly
  2438.     to work better with editors and workbench programs that scan error
  2439.     logs to go to lines with errors.  The format is now:
  2440.  
  2441.         file(line): error TADS-xxxx: message
  2442.  
  2443.     For example:
  2444.  
  2445.         deep.t(1151): error TADS-300: expected colon
  2446.  
  2447.  
  2448.   - The parser now accepts sentences of the form VERB PREP IOBJ DOBJ,
  2449.     where the PREP is *not* part of the verb.  For example, GIVE TO THE
  2450.     MAN THE BALL.  This change has two benefits.  First, while this
  2451.     type of sentence is not common in English, some other languages
  2452.     allow this type of phrasing, so the parser is now somewhat more
  2453.     adaptable to non-English languages.  Second, this allows for
  2454.     object defaulting and command completion when specifying just the
  2455.     indirect object, which was not possible before.  For example, if
  2456.     the player types ASK FOR A BEER, the parser will be able to attempt
  2457.     to provide a default (if one is available), or at least ask for the
  2458.     direct object.  Previous versions would simply say "I don't understand
  2459.     that sentence."  Note that the parser still attempts to combine the
  2460.     verb and preposition into a single phrase; the new action happens
  2461.     only when the verb and preposition don't go together (that is, they
  2462.     haven't been defined together as a "verb =" property of a deepverb).
  2463.     For example, suppose that a line like this appears in a deepverb:
  2464.  
  2465.         verb = 'pick up'
  2466.  
  2467.     In this case, PICK UP THE BOX will use THE BOX as the direct object,
  2468.     just as in previous versions.  Only when the verb-preposition combination
  2469.     is not specifically defined in a verb will the new phrasing be used.
  2470.  
  2471.   - When no preposition is specified between the direct and indirect objects,
  2472.     the parser will now evaluate a new property, nilPrep, in the deepverb
  2473.     object.  This property should return the preposition object that should
  2474.     be used as the preposition between the objects.  Previous versions of
  2475.     TADS always looked for an object that defined the word 'to' as a
  2476.     "preposition =" property.  While 'to' is almost always the correctly
  2477.     the correct preposition to substitute in English, it's obviously the
  2478.     wrong word in other languages; furthermore, the correct word in other
  2479.     languages is sometimes a function of verb.  If no nilPrep property is
  2480.     defined for the deepverb, the parser will still use the object whose
  2481.     "preposition =" property matches the word 'to'.
  2482.  
  2483.   - The class transparentItem in adv.t has been modified so it works better
  2484.     when you define an object that inherits from both transparentItem and
  2485.     container or openable.  First, an ldesc has been added so that the
  2486.     contents of a transparentItem are listed by default with the ldesc.
  2487.     Second, the "look in" command now works on a transparentItem.  In
  2488.     addition, the openable class has been changed so that the "look in"
  2489.     command can be used when an openable is also a transparentItem, even
  2490.     when the openable is closed (because you should be able to see the
  2491.     contents of a transparentItem regardless of whether it's open or closed).
  2492.     Thanks to Ron Hale-Evans for pointing out this problem and finding the
  2493.     solution.
  2494.  
  2495. 2.1.0  04/07/93  new features, enhancements, bug fixes
  2496.  
  2497.   - TADS finally has a way of changing objects and functions in
  2498.     adv.t without changing adv.t itself.  The new mechanism allows
  2499.     you to entirely replace a previously defined object or function
  2500.     with one of your own, and also lets you modify a previously
  2501.     defined object by adding or overriding properties.  Two new
  2502.     keywords have been added to the language to support these new
  2503.     features:  "replace" and "modify".
  2504.  
  2505.     Using these new features, it should be possible to make most
  2506.     of the changes to adv.t that are necessary while writing a game
  2507.     without actually changing the file adv.t itself.  This should
  2508.     make version upgrades much easier to apply, since you shouldn't
  2509.     need to reconcile any changes you have made to adv.t with the
  2510.     new version.
  2511.  
  2512.     High Energy Software requests that you advise us of any changes
  2513.     to adv.t that would facilitate modification and replacement of
  2514.     the objects defined in adv.t.  Examples would include common
  2515.     code fragments that could be moved into a function for easy
  2516.     replacement, and single deepverb objects that should be split
  2517.     into multiple objects.
  2518.  
  2519.     You can replace a previously-defined function with a new
  2520.     definition simply by prefacing your new definition with the
  2521.     keyword "replace"; for example, to replace adv.t's new
  2522.     scoreStatus function, you could do this:
  2523.  
  2524.        #include <adv.t>
  2525.  
  2526.        replace scoreStatus(points, turns)
  2527.        {
  2528.           setscore(cvtstr(pts) + ' points/' + cvtstr(turns) + ' moves');
  2529.        }
  2530.  
  2531.     You can do the same thing with objects.  For example, to replace
  2532.     a verb in adv.t, you could do something like this:
  2533.  
  2534.        #include <adv.t>
  2535.  
  2536.        /* we don't want "buckle", so replace adv.t's fastenVerb */
  2537.        replace fastenVerb: deepverb
  2538.           verb = 'fasten'
  2539.       sdesc = "fasten"
  2540.       prepDefault = toPrep
  2541.       ioAction(toPrep) = 'FastenTo'
  2542.        ;
  2543.  
  2544.     Replacing an object entirely deletes the previous definition of
  2545.     the object, including all inheritance information and vocabulary.
  2546.     The only properties of a replaced object are those defined in the
  2547.     replacement; the original definition is entirely discarded.
  2548.  
  2549.     You can also modify an object, which retains its original definition
  2550.     (including inheritance information, vocabulary, and properties), and
  2551.     allows you to add new properties and vocabulary.  You can also
  2552.     override properties, simply by redefining them in the new definition.
  2553.     The most common addition to an object from adv.t will probably be
  2554.     new verb associations; for example:
  2555.  
  2556.        modify pushVerb
  2557.           verb = 'nudge'
  2558.           ioAction(withPrep) = 'PushWith'
  2559.        ;
  2560.  
  2561.     Note several things about this example.  First, no superclass
  2562.     information can be specified in a "modify" statement; this is because
  2563.     the superclass list for the modified object is the same as for the
  2564.     original object.  Second, note that vocabulary has been added.
  2565.     The additional vocabulary does NOT replace the original vocabulary,
  2566.     but simply adds to the previously-defined vocabulary.  Further note
  2567.     that verb association pseudo-properties, such as doAction and ioAction,
  2568.     are legal in a "modify" definition.
  2569.  
  2570.     In a method that you redefine with "modify", you can use "pass"
  2571.     or "inherited" to refer to the REPLACED method.  In essence, using
  2572.     "modify" renames the original object, and then creates a new
  2573.     object under the original name; the new object is created as a
  2574.     subclass of the original (now unnamed) object.  There is no way
  2575.     to refer to the original object, except indirectly through the
  2576.     new replacement object.  Here's an example of "modify" and "pass":
  2577.  
  2578.         class testClass: object
  2579.         sdesc = "testClass"
  2580.     ;
  2581.  
  2582.         testObj: testClass
  2583.             sdesc =
  2584.         {
  2585.             "testObj...";
  2586.         pass sdesc;
  2587.         }
  2588.         ;
  2589.  
  2590.         modify testObj
  2591.             sdesc =
  2592.         {
  2593.             "modified testObj...";
  2594.         pass sdesc;
  2595.         }
  2596.     ;
  2597.  
  2598.     Evaluating testObj.sdesc results in this display:
  2599.  
  2600.         modified testObj...testObj...testClass
  2601.  
  2602.     However, you can override this behavior for a property by
  2603.     using the replace keyword on the property.  In the example
  2604.     above, we could do this instead:
  2605.  
  2606.         modify testObj
  2607.             replace sdesc =
  2608.         {
  2609.             "modified testObj...";
  2610.         pass sdesc;
  2611.         }
  2612.     ;
  2613.  
  2614.     This would result in the following display for testObj.sdesc:
  2615.  
  2616.         modified testObj...testClass
  2617.  
  2618.     The "replace" keyword before the property definition tells the
  2619.     compiler to completely delete the previous definitions of the
  2620.     property.  This allows you to completely replace the property,
  2621.     and not merely override it, meaning that "pass" and "inherited"
  2622.     will refer to the property actually inherited from the superclass,
  2623.     and not the original definition of the property.
  2624.  
  2625.   - It is now possible for the player to customize the colors used
  2626.     by the runtime.  A small new program, TRCOLOR, is provided to
  2627.     set up the runtime screen colors.  The program is self-explanatory;
  2628.     simply type TRCOLOR at the DOS prompt to invoke it.  Once you've
  2629.     selected your color scheme, TRCOLOR will create a small file
  2630.     called TRCOLOR.DAT (in the current directory); the runtime will
  2631.     read this file in subsequent game sessions.
  2632.  
  2633.     Note that you can use multiple TRCOLOR.DAT files, in much the same
  2634.     way you can use two CONFIG.TC files.  The runtime looks first for
  2635.     TRCOLOR.DAT in the current directory; if no such file is found, the
  2636.     runtime will then look in the directory where TR.EXE resides.  So,
  2637.     you can set up separate color schemes for each game you're playing,
  2638.     and have a default color scheme for games with no specific color
  2639.     scheme of their own.
  2640.  
  2641.   - The user interface of the MAKETRX program has been improved.
  2642.     For compatibility with existing makefiles, the old command line
  2643.     syntax is still allowed; however, you can now omit most of the
  2644.     arguments, and MAKETRX will use convenient new defaults.
  2645.  
  2646.     First, you can now omit the extensions on all the arguments.
  2647.     The extension assumed for the TR.EXE program is .EXE; for the
  2648.     game file it is .GAM; and for the executable output file it is .EXE.
  2649.  
  2650.     Second, you can now omit everything except the name of the game
  2651.     file.  If you omit the name of the TR.EXE program, MAKETRX attempts
  2652.     to find TR.EXE in the same directory as MAKETRX.EXE; so, if you
  2653.     simply keep all of your TADS executables in a single directory,
  2654.     you won't need to specify the location of TR.EXE when running MAKETRX.
  2655.     If you omit the name of the destination file, MAKETRX will use the
  2656.     same name as the game file, with the extension replaced by .EXE.
  2657.  
  2658.     The command line arguments to MAKETRX that are now understood are:
  2659.  
  2660.        maketrx gamefile
  2661.          Converts gamefile.gam into gamefile.exe, using TR.EXE from the
  2662.      same directory as MAKETRX.EXE.
  2663.  
  2664.        maketrx gamefile output
  2665.          Converts gamefile.gam into output.exe, using TR.EXE from the
  2666.      same directory as MAKETRX.EXE.
  2667.  
  2668.        maketrx \tads2\tr.exe gamefile output
  2669.          Converts gamefile.gam into output.exe, using \tads2\tr.exe.
  2670.  
  2671.  
  2672.   - The dobjGen and iobjGen mechanism has been changed slightly.
  2673.     In the original implementation, you could prevent the system
  2674.     from calling dobjGen/iobjGen by defining an appropriate verXoVerb
  2675.     property in the actual object, but NOT in a superclass.  This
  2676.     made it impossible to define a class that had exceptions to
  2677.     dobjGen/iobjGen except by explicitly testing for those verbs
  2678.     in the xobjGen routines.
  2679.  
  2680.     The change is that the system will now skip calling xobjGen
  2681.     if an appropriate verXoVerb/xoVerb property is defined in such
  2682.     a way that it "overrides" xobjGen for the object.  Here's an
  2683.     example:
  2684.  
  2685.        class cursedItem: item
  2686.            dobjGen(a, v, i, p) =
  2687.        {
  2688.            "As you touch <<self.thedesc>>, a bolt of lightning
  2689.            leaps from the object and sends you reeling away!";
  2690.        }
  2691.        iobjGen(a, v, d, p) = { self.dobjGen(a, v, d, p); }
  2692.        verDoInspect(actor) = { pass verDoInspect; }  // allow 'inspect'
  2693.        ;
  2694.  
  2695.     The change means that the presence of verDoInspect in the *class*
  2696.     prevents the system from calling dobjGen when the verb is "inspect",
  2697.     even for subclasses.  With the old system, since the subclass objects
  2698.     themselves didn't define verDoInspect, dobjGen would be called even
  2699.     though the verDoInspect logically overrides the dobjGen.
  2700.  
  2701.   - The restore() intrinsic has been extended to allow your game
  2702.     program to explicitly restore the saved game specified by the
  2703.     user as a parameter to your stand-alone game program.  This is
  2704.     currently only useful on the Macintosh, but the inclusion of
  2705.     code to test for this case will make your game work better on
  2706.     the Macintosh (and possibly other platforms in the future).
  2707.  
  2708.     The new functionality is invoked by calling restore(nil).  If
  2709.     a saved game was specified by the user at start-up time, the
  2710.     game will be restored, and nil will be returned.  If no file
  2711.     was specified, or an error occurred restoring the game, the
  2712.     function returns true.  To use this new behavior, we recommend
  2713.     placing the following code in your init function, before your
  2714.     introductory messages and other startup code:
  2715.  
  2716.        // check for a file to restore specified as a startup parameter
  2717.        if (restore(nil) = nil)
  2718.        {
  2719.            "\b[Restoring saved game]\b";
  2720.            scoreStatus(global.score, global.turnsofar);
  2721.            Me.location.lookAround(true);
  2722.            return;
  2723.        }
  2724.  
  2725.     Note that the run-time will still automatically restore the
  2726.     game provided as a parameter (on the Macintosh) after init returns
  2727.     if you do NOT include this code in init.  The reason for including
  2728.     this code is that it provides your game with greater control over
  2729.     the sequence of events during startup.  If you allow the run-time
  2730.     to perform the restore automatically, your entire init function will
  2731.     be executed; this may be undesirable, because it forces the user to
  2732.     view the entire introductory text even though they'll immediately
  2733.     restore a game after reading it.  If you place the restore(nil) call
  2734.     before your introductory text, the user will be spared the long text
  2735.     display; however, you'll still have complete control over any text
  2736.     that you want the user to see even when restoring a game, such as
  2737.     your copyright message.
  2738.  
  2739.   - New built-in function:  objwords(num), which provides a list of
  2740.     the actual words the user typed to refer to an object used in
  2741.     the current command.  The argument (num) is a number specifying
  2742.     which object you're interested in:  1 for the direct object, or
  2743.     2 for the indirect object.  The return value is a list of strings;
  2744.     the strings are the words used in the command.  If a special
  2745.     word, such as "it", "them", or "all", was used to specify the
  2746.     object, the list will have a single element, which is the special
  2747.     word used.
  2748.  
  2749.     Examples:
  2750.  
  2751.        >take all
  2752.        objwords(1) -> ['all']
  2753.        objwords(2) -> []
  2754.  
  2755.        >put all in red box
  2756.        objwords(1) -> ['all']
  2757.        objwords(2) -> ['red' 'box']
  2758.  
  2759.        >put blue box in it
  2760.        objwords(1) -> ['blue' 'box']
  2761.        objwords(2) -> ['it']
  2762.  
  2763.        >put blue folder and green book in red box
  2764.        blue folder:
  2765.        objwords(1) -> ['blue' 'folder']
  2766.        objwords(2) -> ['red' 'box']
  2767.        green book:
  2768.        objwords(1) -> ['green' 'book']
  2769.        objwords(2) -> ['red' 'box']
  2770.  
  2771.     This function could potentially be useful in such cases as
  2772.     "ask actor about object", because it allows you to determine
  2773.     much more precisely what the player is asking about than would
  2774.     otherwise be possible.
  2775.  
  2776.   - The setit() function now takes nil as a parameter; this prevents
  2777.     using "it" in a command until another object has been referenced.
  2778.     nil can be used for "him" and "her" as well, as described below.
  2779.  
  2780.   - Enhancements to the setit() built-in function:  you can now directly
  2781.     set the 'him', 'her', and 'them' values using the setit() function.
  2782.  
  2783.        - To set 'them', simply call setit() with a list value:
  2784.          setit([redBook blueBook boots]);
  2785.  
  2786.        - To set 'him', add a second argument value of 1 to the call:
  2787.          setit(joe, 1);
  2788.  
  2789.        - To set 'her', add a second argument value of 2:
  2790.          setit(harriet, 2);
  2791.  
  2792.   - The restart() built-in function now takes an optional set of
  2793.     arguments:  a pointer to a function, and a parameter value for
  2794.     the function (if one is provided, the other is also required, but
  2795.     both can be omitted).  If they're provided, TADS calls the function
  2796.     with the provided parameter value *after* resetting the game, and
  2797.     before running the init() function.  This allows you make the game
  2798.     start slightly differently after a restart than on the initial startup.
  2799.     adv.t uses this feature to call the function initRestart, with the
  2800.     parameter value global.initRestartParam, upon restart.  The initRestart
  2801.     function defined in adv.t simply sets the flag global.restarting to
  2802.     true.  Your game can test global.restarting (in the init function or
  2803.     elsewhere) to determine whether the game has been restarted, or is
  2804.     being run for the first time.  You can also replace initRestart()
  2805.     with your own function if you wish to do something more complicated;
  2806.     in this case, if you wish to pass information to the function, you
  2807.     can simply store it in global.initRestartParam, and it will be passed
  2808.     to the function automatically by adv.t upon restarting.
  2809.  
  2810.   - New built-in function:  inputkey() reads a single keystroke from
  2811.     the keyboard.  The function takes no arguments.  When called,
  2812.     inputkey() will flush any pending output text, then pause the game
  2813.     until the player hits a key.  It then returns a string containing
  2814.     the single key hit by the player.  Note that the function does NOT
  2815.     provide a portable mechanism for reading non-standardized keys;
  2816.     special keys such as cursor arrow keys and function keys will return
  2817.     a string specific to the type of computer being used.  Your game
  2818.     will not be portable if you make use of any non-standardized key
  2819.     values returned by inputkey().  To ensure portability, use inputkey()
  2820.     strictly with standard ASCII keys (alphabetic, numeric, and punctuation
  2821.     keys).  It is also fully portable if you simply ignore the return value
  2822.     and use the function only to pause and wait for a key.
  2823.  
  2824.   - Several changes have been made for better national language
  2825.     support.  First, the DOS version now allows 8-bit characters
  2826.     (characters in the extended character set, with ASCII code
  2827.     from 128 to 255) in text displayed by the game, vocabulary
  2828.     words, and player commands.  Characters in the extended character
  2829.     set are always considered to be alphabetic, so these characters
  2830.     can only be used in input as parts of words (hence, symbols
  2831.     from the extended character set that appear as punctuation
  2832.     marks can't be used as punctuation in player commands).
  2833.  
  2834.   - The debugger now has "More" mode in the command window.  When
  2835.     a single display won't fit in the window (for example, a long
  2836.     stack traceback), the debugger will prompt with "[More]" each
  2837.     time the window fills up.  Hit the space bar to scroll by a
  2838.     whole screen, or the Return/Enter key to scroll by a single line.
  2839.  
  2840.   - The debugger has a new "call history" feature.  This feature
  2841.     captures information about every function and method call,
  2842.     including argument lists and return values (if any), and saves
  2843.     the information for future inspection.  Several new commands
  2844.     have been added to the debugger to support call history:
  2845.  
  2846.         c+    Enables call history, and clears previous history.
  2847.         c-    Disables call history capture.
  2848.         cc    Clears all current history information.
  2849.         c     Displays current history information.
  2850.  
  2851.     The reason that call history can be enabled and disabled is
  2852.     that enabling the feature slows down the debugger substantially,
  2853.     because it must store information every time a method is called.
  2854.  
  2855.     This feature could be useful if you're trying to figure out the
  2856.     sequence of method calls that occurs during the execution of
  2857.     a command.  At the debugger command line, type c+ to turn on
  2858.     call history; then, type g to resume your game.  Type the command
  2859.     that you want to debug, then type DEBUG at the game prompt to
  2860.     return to the debugger.  Now type c- to turn off call history,
  2861.     and c to display the history information from the command you
  2862.     just executed.  This will allow you to see every method and
  2863.     function that was called by TADS, as well as all the methods
  2864.     and functions called by your code.
  2865.  
  2866.     The call history display will have each function/method call indented
  2867.     by a number of spaces indicating the nesting depth; any method/function
  2868.     called by TADS will be at the left margin, any methods/functions called
  2869.     by the first one will be indented one space, any methods/functions
  2870.     called by those will be indented two spaces, and so on.  The return
  2871.     values will be indented by the same number of spaces as the function
  2872.     itself was.  Note that a return value may be separated from its
  2873.     entrypoint by several lines, because calls made by the function
  2874.     will appear between the function entry and the return value.
  2875.  
  2876.   - Another new national language feature is the addition of
  2877.     several new parser-called user functions that allow better
  2878.     user control over the generation of parser messages.  The
  2879.     new functions have been added because some people have found
  2880.     that the parseError() function is not sufficiently flexible
  2881.     for some situations, because it only allows changing the text
  2882.     of messages on a piecewise basis; when complete messages need
  2883.     to be built out of several pieces, it's necessary to be able to
  2884.     take over the entire process of building the message.  The new
  2885.     functions allow full control of the generation of certain messages.
  2886.  
  2887.     parseAskobj(v, ...):  This function is called when the parser
  2888.     needs to ask the player for a direct or indirect object to complete
  2889.     the command.  For example, if the player just types "take", and
  2890.     several objects are present that could be taken, the parser must
  2891.     ask the player what to take.  If a direct object is being requested,
  2892.     the function will have only one argument (the verb).  If an indirect
  2893.     object is being requested, the function will have *two* arguments;
  2894.     the second argument will be the preposition.  Note that the preposition
  2895.     can be nil, in which case you can assume that "to" is to be used.
  2896.     The implementation below emulates the default behavior.
  2897.  
  2898.         parseAskobj: function(v, ...)
  2899.     {
  2900.         "What do you want to <<v.sdesc>>";
  2901.         if (argcount = 2)
  2902.         {
  2903.             local p := getarg(2);
  2904.             " it << p ? p.sdesc : "to" >>";
  2905.         }
  2906.         "?";
  2907.     }
  2908.  
  2909.     parseDisambig(string, list):  This function is called by the
  2910.     parser when objects need to be disambiguated.  If this optional
  2911.     function is provided, it is called with the string that the player
  2912.     typed which is in need of disambiguation, and a list of the objects
  2913.     that match the string.  The implementation below emulates the
  2914.     parser's default behavior.
  2915.  
  2916.         parseDisambig: function(str, lst)
  2917.         {
  2918.             local i, tot, cnt;
  2919.         
  2920.             "Which << str >> do you mean, ";
  2921.             for (i := 1, cnt := length(lst) ; i <= cnt ; ++i)
  2922.             {
  2923.                 lst[i].thedesc;
  2924.                 if (i < cnt) ", ";
  2925.                 if (i+1 = cnt) "or ";
  2926.             }
  2927.             "?";
  2928.         }
  2929.  
  2930.     parseError2(v, d, p, i):  The parser calls this function to
  2931.     generate the default error message stating that the verb attempted
  2932.     isn't accepted by the objects involved; this happens when either
  2933.     the indirect object doesn't define an appropriate verIoXxxx method,
  2934.     or the direct object doesn't define an appropriate verDoXxxx method.
  2935.     Only one of 'd' (direct object) or 'i' (indirect object) will be
  2936.     non-nil.  If 'i' is nil, so will 'p' (preposition).  The verb, 'v',
  2937.     will never be nil.  Note that 'p' can be nil even when 'i' is not,
  2938.     in which case you should assume that the preposition is "to".
  2939.     The implementation below behaves the same as the parser's default.
  2940.  
  2941.         parseError2: function(v, d, p, i)
  2942.         {
  2943.             "I don't know how to << v.sdesc >> ";
  2944.             if (d)
  2945.                 "<< d.thedesc >>.";
  2946.             else
  2947.             "anything << p ? p.sdesc : "to" >> << i.thedesc >>.";
  2948.         }
  2949.  
  2950.     parseDefault(obj, prp):  This function is called when the parser
  2951.     is assuming a default object.  If a default direct object is being
  2952.     assumed, prp (the preposition) will be nil; otherwise, prp will have
  2953.     the object corresponding to the preposition preceding the indirect
  2954.     object.  The implementation below provides the default behavior.
  2955.  
  2956.         parseDefault: function(obj, prp)
  2957.         {
  2958.             "(";
  2959.             if (prp) "<< prp.sdesc>> ";
  2960.             obj.thedesc;
  2961.             ")";
  2962.         }
  2963.  
  2964.     Note that all three of these new functions are optional.  If any
  2965.     is omitted, the parser uses the default behavior, so existing games
  2966.     will run unchanged.  You can include any one without including the
  2967.     others; these new functions are all independent.  Note also that
  2968.     the default parser behavior continues to use parseError the same
  2969.     way it has since parseError was introduced; however, when these
  2970.     new functions are provided, the corresponding parseError calls will
  2971.     obviously no longer be made.
  2972.  
  2973.   - COMPATIBILITY NOTE:  By default, the .GAM files produced by
  2974.     the 2.1.0 compiler will NOT be compatible with previous
  2975.     versions of the runtime, due to several changes to the .GAM
  2976.     file format.  However, a new compiler option has been added
  2977.     that allows you to specify which .GAM file format to produce:
  2978.  
  2979.       -fv a   produces .GAM format compatible with 2.0.14 or earlier
  2980.       -fv b   produces game file format requiring 2.1.0 or later
  2981.       -fv *   (default) produces latest file format (currently b)
  2982.  
  2983.     If you want your game to be compatible with older versions of
  2984.     the runtime, use -fv a.  The 2.1.0 runtime is compatible with
  2985.     .GAM files produced by ANY version of the compiler; the runtime
  2986.     automatically detects which file format version it is reading.
  2987.  
  2988.     Note that using -fv a will prevent you from being able to call
  2989.     an external function from within the init function (see the bug
  2990.     fix described below).  In addition, even when using -fv a, since
  2991.     previous versions of the run-time did not provide the new built-in
  2992.     functions, your game will be incompatible with runtimes prior to
  2993.     2.1.0 -- regardless of whether you use -fv a or not -- if you
  2994.     use any new built-in functions.
  2995.  
  2996.     In the future, if there is another incompatible .GAM file format
  2997.     change, additional -fv options will be added to the new compiler.
  2998.  
  2999.   - One of the changes to the .GAM file format makes it much more
  3000.     compressible with archiving tools (such as ZIP).  Previous
  3001.     .GAM files typically compressed by only 10 to 20%; the files
  3002.     produced with file format B are generally compressible by 40
  3003.     to 50%.
  3004.  
  3005.   - runfuses and rundaemons had a bug that reset the run-time
  3006.     stack, causing problems if a nested method or function
  3007.     called these functions.  This has been corrected.
  3008.  
  3009.   - Subtracting one list from another didn't work as documented.
  3010.     This has been corrected.
  3011.  
  3012.   - In previous versions, external functions could not be called
  3013.     while the init function was running.  This was an unintentional
  3014.     side-effect of the way external functions were loaded, and the
  3015.     problem has been corrected.  External functions can now be called
  3016.     at any time.
  3017.  
  3018.   - A new warning has been added that can help you track down
  3019.     unterminated strings.  Whenever the compiler sees a line that
  3020.     begins with a semicolon or close brace (';' or '}') inside
  3021.     a string, it will issue a warning.  While this is just a guess
  3022.     that the string may be unterminated, it's often right, especially
  3023.     if you follow the general formatting style used by adv.t:  always
  3024.     end a function with a brace in the first column of a new line,
  3025.     and always end an object with a semicolon in the first column of
  3026.     a new line.
  3027.  
  3028.     Note that we strongly recommend that you follow this formatting
  3029.     style in your code, both for general readability and because it
  3030.     may enhance your code's compatibility with future High Energy
  3031.     Software products that use assumptions about formatting style
  3032.     that are similar to that used to generate the new unterminated
  3033.     string warning.
  3034.  
  3035.   - Several small enhancements and bug fixes have been made to
  3036.     adv.t:
  3037.  
  3038.        - A new property has been added to nestedroom objects:
  3039.          statusPrep, which displays "on" or "in" (or whatever),
  3040.      as appropriate, for messages such as "Spaceship, in chair".
  3041.      This defaults to "in" for nestedroom, and "on" for beditem.
  3042.      Other nestedroom objects you define may want to customize it.
  3043.  
  3044.        - There was a bug that allowed the player to throw a fixeditem
  3045.          that was (indirectly) being carried (for example, a fixeditem
  3046.          that is part of another object that can be carried) at something.
  3047.      This has been fixed.
  3048.  
  3049.        - The follower class did not 'exit' at the end of its actorAction.
  3050.          This has been fixed.
  3051.  
  3052.        - The follower class now makes use of iobjGen and dobjGen to respond
  3053.          with an appropriate message ("the actor is no longer here") to
  3054.      any command other than "follow".
  3055.  
  3056.        - The clothingItem class has been enhanced to allow "get out of"
  3057.          to be used to take off the item.
  3058.  
  3059.        - All of the verbs containing the word "look" now have synonyms
  3060.          with "l" as well:  l at, l on, l in, l under, l around, l thru,
  3061.      and so on.
  3062.  
  3063.        - A bug has been fixed that allowed the command "take all from foo"
  3064.          to remove the contents of "foo" even if it was closed.  The
  3065.      change is to the doDefault method in takeVerb.
  3066.  
  3067.        - The vehicle class has been adjusted so that the player can't
  3068.          take a vehicle or otherwise manipulate it while the player is
  3069.      currently in the vehicle -- this is important for things such
  3070.      as rubber rafts which can be used both as vehicles and ordinary
  3071.      carryable items.  dobjGen and iobjGen are used to accomplish
  3072.          this; the only allowed verbs on a vehicle while it's occupied
  3073.      by the player are inspectVerb, getOutVerb, outVerb, and putVerb
  3074.      with the vehicle as an indirect object (allowing objects to be
  3075.      put into the vehicle while it's occupied).  If you want to allow
  3076.      additional verbs in a particular vehicle, override dobjGen or
  3077.      iobjGen as appropriate, and simply return if the verb matches
  3078.      any of the verbs you wish to add:
  3079.  
  3080.          dobjGen(a, v, i, p) =
  3081.          {
  3082.              // allow "launch" and "land" while in the magic raft
  3083.              if (v <> launchVerb and v <> landVerb)
  3084.              pass dobjGen;
  3085.          }
  3086.  
  3087.   - The compiler now detects usage (both explicit and implicit)
  3088.     of "self" in functions.  This has always been illegal, but
  3089.     in previous versions the compiler did not notice; any uses
  3090.     of "self" in functions resulted in a run-time error (often
  3091.     a mysterious error, such as a cache manager severe error and
  3092.     abnormal termination due to a reference to a non-existent
  3093.     object).  This was especially troublesome when a property
  3094.     name was used as a local variable when the local variable
  3095.     wasn't declared; since the v2 compiler assumes "self" in
  3096.     references to properties that don't include an object
  3097.     qualification, the compiler would silently turn an undefined
  3098.     variable usage into a reference to "self".  The compiler will
  3099.     now flag a new error in these cases:  TADS-344, "self" is not
  3100.     valid in this context.  If you get this error without an
  3101.     explicit reference to "self", you probably have an implicit
  3102.     reference, which means you probably are using an undeclared
  3103.     local variable.  Adding a "local" declaration for the variable
  3104.     should clear the error.
  3105.  
  3106.   - "Her" was not set properly, even when the isHer property was
  3107.     set to true for an object.  This has been corrected.
  3108.  
  3109.   - A new compiler option has been added:  -v, for "verbosity".
  3110.     This option lets you tell the compiler how much warning
  3111.     information you'd like to see.  By default, the verbosity
  3112.     level is 0 (zero), which causes certain warnings to be
  3113.     suppressed.  You can specify -v followed by a number to
  3114.     set a higher verbosity level.  So far, only the messages
  3115.     listed below are affected by -v, but the verbosity level
  3116.     for certain warnings may be changed in the future (and new
  3117.     warnings may be added at high verbosity levels).  Currently,
  3118.     the general meaning of the verbosity levels is:  0, report
  3119.     only serious errors and warnings; 1, report suspicious
  3120.     situations that may or may not indicate errors; 2, report
  3121.     all information, including general warning information that
  3122.     usually does not indicate any actual problem.
  3123.  
  3124.   - A new compiler option has been added:  -e file, for "error logging".
  3125.     This option captures all messages generated by the the compiler to
  3126.     the specified file.  Messages are also displayed interactively as
  3127.     normal.  WARNING: if the file specified with -e already exists, it
  3128.     is overwritten with the error information.
  3129.  
  3130.   - The compiler warning messages about "object not found" for the
  3131.     optional objects (preinit, preparse, parseError, commandPrompt)
  3132.     are now suppressed if the verbosity level is less than 2.
  3133.     If you specify -v2 (or -v with a higher number than 2), these
  3134.     messages will be displayed for all optional objects not found;
  3135.     otherwise, no warnings will be generated.
  3136.  
  3137.   - The compiler warning messages about "#include file already included"
  3138.     are now suppressed if the verbosity level is less than 1.
  3139.  
  3140.  
  3141. 2.0.14  02/10/93  bug fixes, minor enhancements
  3142.  
  3143.   - A new backslash code has been added to the output formatter that
  3144.     causes the formatter to pass the next two bytes unchanged.
  3145.     This has been added primarily for 16-bit character sets, to allow
  3146.     two-byte characters that contain a backslash ('\', ASCII 92) as
  3147.     one of their two bytes to be passed through the formatter without
  3148.     interpretation as part of a backslash sequence.  The new code
  3149.     is "\-"; the two bytes following the \- are not interpreted by
  3150.     the formatter.  For example:
  3151.  
  3152.        "\-\bTesting...\nDone!";
  3153.  
  3154.     displays:
  3155.  
  3156.        \bTesting...
  3157.        Done!
  3158.  
  3159.     Note that the "\b" sequence is not interpreted as a blank line,
  3160.     as it would normally be, but is simply displayed, because the \-
  3161.     suppresses any interpration of the next two bytes.  The "\n",
  3162.     however, is interpreted as a newline as normal, since it is not
  3163.     quoted by a \- sequence.
  3164.  
  3165.   - You can now break out of an infinite loop in your game while
  3166.     running under the debugger.  On DOS, if your game goes into a loop,
  3167.     hit the Control + Break keys - the loop should immediately be
  3168.     aborted and control returned to the debugger command line.
  3169.     The Control-Break sequence also works with the runtime; it
  3170.     causes control to be returned to the player command line.
  3171.     Note that the interrupted command is automatically undone, so
  3172.     the interrupt sequence will not leave the game in an inconsistent
  3173.     state.  Note also that only long loops can be interrupted; the
  3174.     system only checks for interruptions once every several hundred
  3175.     instructions for greater efficiency.
  3176.  
  3177.   - The debugger will now catch run-time errors, activating the
  3178.     debugger command line when an error occurs.  The source will
  3179.     be positioned at the location of the error, as though a breakpoint
  3180.     had been set there, and the error message will be displayed.  Local
  3181.     variables can be evaluated as normal to help determine the cause of
  3182.     the error.  When you resume execution (with Trace, Step, or Go),
  3183.     the current command will be aborted and control will return to the
  3184.     player command prompt.  Note that there's no way to "fix" the error
  3185.     once it's been caught, but you can at least see exactly where the
  3186.     error occurred and determine the conditions that caused it.  Note
  3187.     also that certain types of errors, such as memory management errors,
  3188.     will not invoke the debugger; only errors that are directly caused
  3189.     by an error in your game program will trap to the debugger.
  3190.  
  3191.   - The debugger incorrectly reported files as "not found" in the
  3192.     list of modules produced by the "fl" command.
  3193.  
  3194.   - The runtime was inconsistent in its calls to ioDefault.  Sometimes
  3195.     it called ioDefault(actor, prep), and other times it called it as
  3196.     ioDefault(actor, prep, dobj) - this made it impossible to define the
  3197.     method correctly if argument checking was enabled.  This has been
  3198.     corrected so that the dobj parameter is never included.  When attempting
  3199.     to identify a default indirect object, the parser never has a direct
  3200.     object available, since the indirect object must be resolved first;
  3201.     hence, the dobj that was occasionally being passed by the parser was
  3202.     always nil.  The unnecessary extra parameter has been removed:  the
  3203.     method is now always called as ioDefault(actor, prep).
  3204.  
  3205.   - The compiler generated incorrect code if the implicit "self" object
  3206.     was used to reference an object (that is, a property was used without
  3207.     an object specifier).  This resulted in "invalid opcode" errors at
  3208.     run-time.
  3209.  
  3210.   - The compiler sometimes complained that an included file couldn't
  3211.     be found, even when the included file was explicitly loaded as part
  3212.     of a precompiled header.  This happened any time the included file
  3213.     was not in the current directory at compilation time.
  3214.  
  3215.   - The compiler aborted with an "assertion failure" (which indicates
  3216.     that the compiler detected that it was in an internally inconsistent
  3217.     state, which should not be attainable under any circumstances) when
  3218.     the game program used a variable or expression on the right hand
  3219.     side of a dot operator and an object on the left hand side.
  3220.  
  3221. 2.0.13  01/16/93  enhancements and bug fixes
  3222.  
  3223.   - If a vocabulary word contained a single quote character, the
  3224.     word could not be matched at run-time.
  3225.  
  3226.   - The run-time now allows all characters from the extended character
  3227.     set (ASCII codes above 127) to be displayed.  The run-time
  3228.     previously converted some extended characters into spaces.
  3229.  
  3230.   - The compiler did not allow a label to precede the first goto
  3231.     that referred to the label.
  3232.  
  3233.   - The debugger will now stop at a breakpoint in a method that
  3234.     is inherited by an object.  For example, if a breakpoint is
  3235.     set at room.lookAround, and startroom inherits lookAround
  3236.     from the class room, the debugger will stop at startroom.lookAround.
  3237.     It does not, however, stop on startroom.lookAround if startroom
  3238.     overrides lookAround.
  3239.  
  3240.   - The compiler will now flag an assignment to an undeclared
  3241.     symbol as an error.  It previously assumed that the symbol
  3242.     referred to a property, with an implicit object of "self".
  3243.     This was almost never desirable, because this type of
  3244.     assignment was most often coded in error -- the game author
  3245.     usually meant to code an assignment to a local variable, but
  3246.     either misspelled the variable name or forgot to declare it.
  3247.  
  3248.   - remfuse/remdaemon/unnotify no longer signal an error if the
  3249.     item being removed is not active.  Several game authors have
  3250.     indicated that this error is not helpful, since it makes it
  3251.     impossible to unconditionally remove a fuse -- you have to
  3252.     check to make sure it hasn't fired yet, which create a lot
  3253.     of unnecessary overhead.
  3254.  
  3255.   - NEW BUILT-IN FUNCTION:  intersect(list1, list2) returns the
  3256.     intersection of two lists; that is, it returns the list of
  3257.     all of the elements of the shorter of list1 and list2 that
  3258.     are also in the other list.  For example:
  3259.  
  3260.         [1 2 3 4 5] and [1 3 5 7]     ->    [1 3 5]
  3261.         ['abc' 'def'] and ['abc']     ->    ['abc']
  3262.  
  3263.     This new function can be used to improve performance in cases
  3264.     where (effectively) one list of items is being searched for
  3265.     the presence of another list of items.
  3266.  
  3267.   - NEW BUILT-IN FUNCTION:  runfuses() runs all expired fuses, if any.
  3268.     Returns true if any fuses expired, nil otherwise.  This function has
  3269.     been added to allow greater control over fuse processing.  Note that
  3270.     fuses set with both the setfuse() and notify() built-in functions
  3271.     are run.  This function takes no arguments.
  3272.  
  3273.   - NEW BUILT-IN FUNCTION:  rundaemons() runs all daemons.  This function
  3274.     runs daemons set with both the setdaemon() and notify() functions.
  3275.     rundaemons() takes no arguments and returns no value.
  3276.  
  3277.   - NEW BUILT-IN FUNCTION:  getfuse allows you to determine if a fuse
  3278.     (set with either setfuse or notify) is active.  It returns nil if
  3279.     the fuse is not active (i.e., it has been activated or removed),
  3280.     or the number of turns left.
  3281.  
  3282.     For setfuse() fuses:   getfuse(fuse_func, parameter)
  3283.     For notify() fuses:    getfuse(object, &message)
  3284.  
  3285.   - NEW BUILT-IN FUNCTION:  gettime() returns the current time.  The
  3286.     time is returned as a list of numeric values for easy processing by
  3287.     your game:
  3288.  
  3289.       [year month day weekday yearday hour minute second elapsed]
  3290.  
  3291.     The specific meanings of the values are:
  3292.  
  3293.           year        - calendar year (e.g., 1992).
  3294.           month       - month number (January = 1, February = 2, etc.)
  3295.           day         - number of the day within the current month
  3296.           weekday     - day of the week (1 = Sunday, 2 = Monday, etc.)
  3297.           yearday     - day of the year (1 = Jan 1)
  3298.           hour        - hour of the day on 24-hour clock (midnight = 0,
  3299.                         noon = 12, 3 PM = 15, etc.)
  3300.           minute      - minute within the hour (0 to 59)
  3301.           second      - second within the minute (0 to 59)
  3302.           elapsed     - the number of seconds since January 1, 1970,
  3303.                         00:00:00 GMT.  This last value is useful for
  3304.                         computing the difference between two points
  3305.                         in time.
  3306.  
  3307.   - NEW FEATURE:  The parser now calls an additional method in
  3308.     each direct and indirect object under certain circumstances.
  3309.     These new methods are called dobjGen (general use of an object
  3310.     as a direct object) and iobjGen.  These methods are called
  3311.     immediately prior to the appropriate verXo<Verb> method.  The
  3312.     sequence of calls depends on the command, as detailed below.
  3313.  
  3314.     The purpose of these methods is to allow you to define a catch-all
  3315.     routine that is called whenever an object is used in a command.
  3316.     It is sometimes desirable to be able to take some action whenever
  3317.     an object is mentioned, regardless of the verb involved.  For
  3318.     example, you might wish to define a cursed object that damages
  3319.     the player (such as by taking away a treasure) whenever the
  3320.     object is touched or manipulated in any way; these new methods
  3321.     make it possible to do this without having to override every
  3322.     possible verb handler.
  3323.  
  3324.     When a command is issued with an indirect object, the parser
  3325.     checks to see if the indirect object *directly* defines the
  3326.     io<Verb> method.  If not, the parser calls iobj.iobjGen(actor,
  3327.     verb, dobj, prep).  The parser then checks to see if the direct
  3328.     object *directly* defines the verDo<Verb> method.  If not, the
  3329.     parser calls dobj.dobjGen(actor, verb, iobj, prep).
  3330.  
  3331.     When a command is issued with only a direct object, the parser
  3332.     checks to see if the object *directly* defines the do<Verb> method.
  3333.     If not, the parser calls dobj.dobjGen(actor, verb, nil, nil).
  3334.  
  3335.     Note that an object "directly defines" a method if the method
  3336.     is defined in the object itself -- that is, the object does
  3337.     not merely inherit the method from its class.
  3338.     
  3339.     These new methods have no return value, and need not do anything.
  3340.     If they're undefined, the behavior is exactly the same as in
  3341.     previous versions.  So, existing games should continue to run
  3342.     unchanged.
  3343.  
  3344.     The reason that these methods are not called when the object
  3345.     directly defines an appropriate verb handler is that these
  3346.     methods are intended as a generic catch-all verb handler.
  3347.     When a specific handler for the current verb is already defined
  3348.     in the object, there should be no need to call the generic
  3349.     handler, since the object already defines specific behavior
  3350.     for that verb.
  3351.  
  3352.  
  3353. 2.0.12  No such release (for internal release coordination)  bug fixes
  3354.  
  3355.   - Switch statements did not properly process all datatypes.
  3356.  
  3357.   - Assignment operations did not work correctly on list elements.
  3358.     For example:  l := [1 2 3]; l[2] += 5; did not properly leave
  3359.     the value of l as [1 7 3].
  3360.  
  3361. 2.0.11  12/20/92  bug fixes
  3362.  
  3363.   - Goto statement labels were occasionally not released properly,
  3364.     resulting in spurious internal errors.
  3365.  
  3366.   - The 'continue' statement did not work as documented in 'for'
  3367.     statements.  Instead of jumping to the re-initializer expression,
  3368.     as it now does, the 'continue' incorrectly jumped to the condition.
  3369.  
  3370.   - The run-time is slightly smaller and faster.
  3371.  
  3372.   - The compiler did not process locals correctly when multiple disjoint
  3373.     blocks within a function or method had locals, and a later block had
  3374.     fewer locals than a previous block (yes, it's a somewhat obscure bug).
  3375.  
  3376. 2.0.10  No such release (to synchronize with Mac release levels)
  3377.  
  3378. 2.0.9  12/12/92  MS-DOS bug fixes and new features
  3379.  
  3380.   - The file selector dialog displayed incorrect information when a
  3381.     directory name that used all 11 characters was displayed.
  3382.  
  3383.   - The file selector now saves and restores all default directory and
  3384.     disk information.  The current disk, and the current directory on
  3385.     each disk, will be the same when TR is terminated as it was when
  3386.     TR was first run.  (This applies to TDB as well.  It's particularly
  3387.     important for TDB, because TDB needs to have the source files in
  3388.     the current working directory if an absolute path was not specified
  3389.     with -I.)
  3390.  
  3391.   - NEW FEATURE:  the new user function commandPrompt, if provided by
  3392.     the user's game program, will be called prior to each player command.
  3393.     If the commandPrompt function is provided, the default ">" prompt is
  3394.     NOT displayed; if no commandPrompt function is defined, the default ">"
  3395.     is used.  This should not affect existing games at all, unless a game
  3396.     defines its own function, method, or property called commandPrompt
  3397.     having a different purpose.  The commandPrompt function returns no
  3398.     value.  The function takes a single argument:  a number, indicating
  3399.     the type of command that the system is prompting for:
  3400.  
  3401.        0  - normal command
  3402.        1  - command after invalid word (allowing "oops" to be used)
  3403.        2  - disambiguation (after "which x do you mean..." question)
  3404.        3  - command after askdo (after "what do you want to x?")
  3405.        4  - command after askio
  3406.  
  3407.     Note that the default prompt in all cases is simply ">", and in all
  3408.     cases a new command can be entered.  However, when the type code is
  3409.     2, 3, or 4, a question has just been displayed by the run-time, so
  3410.     the commandPrompt function may want to suppress any pre-command
  3411.     information or prompt text.  Case 1 is generally identical to case 0.
  3412.  
  3413.     NOTE:  As with the other optional user-provided functions, the
  3414.     compiler will issue a warning message if commandPrompt is not
  3415.     defined by your game.  If your game doesn't provide a commandPrompt
  3416.     function, you can ignore this warning.  The warning is provided so
  3417.     that, if you intended to provide a commandPrompt function, you will
  3418.     be informed if the compiler didn't find it (which could mean that
  3419.     you forgot to define it, or misspelled it).
  3420.  
  3421.   - NEW FEATURE:  A new built-in function has been added, which allows
  3422.     the game program to suppress the display of text that would normally
  3423.     be displayed with double-quoted strings or the say() function.  The
  3424.     function is called outhide(), and it takes one argument:  a flag,
  3425.     indicating whether to suppress or re-enable the display of output.
  3426.     If the flag is true, output is suppressed; if the flag is nil, output
  3427.     is re-enabled.  Any output that occurs between outhide(true) and
  3428.     outhide(nil) is discarded.  However, outhide(nil) returns a value
  3429.     indicating whether any output did in fact occur since the call to
  3430.     outhide(true); this allows you to determine if any output would have
  3431.     occurred, even though the output is not seen by the player.  Note
  3432.     that this is effectively the same mechanism used by the player command
  3433.     parser for noun disambiguation using the verDoXxx and verIoXxx
  3434.     methods, as described in the TADS author's manual.  There is no way
  3435.     to recover the text that was suppressed by outhide(); the text is
  3436.     simply discarded, so the only information available is whether any
  3437.     text was generated.
  3438.  
  3439. 2.0.8  12/03/92  (tc/tdb 2.0.7, tr 2.0.8) MS-DOS bug fixes and minor changes
  3440.  
  3441.   - The display initialization code was incorrectly attempting to clear
  3442.     a zero-line region of the display.  This resulted in extremely long
  3443.     delays on some computers (due to an incorrect BIOS call made by TADS).
  3444.  
  3445.   - NEW FEATURE:  When the keyword $$ABEND is typed as the entire command,
  3446.     the run-time immediately terminates and returns to DOS.  This emergency
  3447.     escape is provided so that TR can be terminated if the game somehow
  3448.     gets into a state where a more graceful exit is not possible.
  3449.  
  3450.   - The compiler did properly detect when an undefined object was used
  3451.     as the superclass of another object.  This generally resulted in
  3452.     unpredictable behavior during execution of preinit.
  3453.  
  3454.   - NEW FEATURE:  The parser now calls two new optional methods in the
  3455.     game program.  These new methods are intended to help speed up the
  3456.     identification of words when many objects have the same vocabulary.
  3457.     If the new methods are not present, behavior is the same as before,
  3458.     so existing games will run unchanged.  The new methods are validDoList
  3459.     and validIoList; they are associated with the "deepverb" object for
  3460.     the current command.  They are called with three parameters:  the actor,
  3461.     the prep, and the other object (indirect object for validDoList and
  3462.     direct object for validIoList; the value of the parameter will be nil
  3463.     if not applicable).  These methods are called prior to the disambiguation
  3464.     pass (using verDoXxx/verIoXxx), and prior to testing any objects with
  3465.     validDo/validIo.
  3466.  
  3467.     The return value of validDoList/validIoList is a list of all of the
  3468.     valid objects for the verb.  It is fine for these methods to return
  3469.     *too many* objects, since each object is still tested with validDo
  3470.     (or validIo) and the appropriate verDoXxx/verIoXxx methods.  Generally,
  3471.     these methods should simply return a list of all of the accessible
  3472.     objects in the actor's current location (or the actor's location's
  3473.     location), plus a list of all of the "floating" objects (which use
  3474.     methods for the location properties).
  3475.  
  3476.     An appropriate definition for validDoList in the deepverb object
  3477.     appears below:
  3478.  
  3479.        validDoList(actor, prep, iobj) =
  3480.        {
  3481.            local ret;
  3482.           local loc;
  3483.  
  3484.        loc := actor.location;
  3485.        while (loc.location) loc := loc.location;
  3486.        ret := visibleList(actor) + visibleList(loc)
  3487.               + global.floatingList;
  3488.        return(ret);
  3489.        }
  3490.  
  3491.     This same definition (with the name changed) is appropriate
  3492.     for validIoList in deepverb.  This returns a list of all of the
  3493.     objects visible in the current location, plus the global list of
  3494.     all floating objects; this should be a superset of the list of
  3495.     accessible objects in most games.  The only verbs that normally
  3496.     requires a different value of validIoList/validDoList are verbs
  3497.     such as "ask" and "tell" that allow any object (whether accessible
  3498.     or not) to be used as indirect objects; for these, simply use this
  3499.     definition:
  3500.  
  3501.        validIoList = nil
  3502.  
  3503.     This takes advantage of the reverse compatibility feature:  when the
  3504.     method returns nil, all objects with matching vocabulary are used.
  3505.  
  3506.     The one additional game change required to take advantage of this
  3507.     new feature is that global.floatingList must be built during
  3508.     initialization.  This can be done easily with the following loop:
  3509.  
  3510.        global.floatingList := [];
  3511.        for (o := firstobj(floatingItem) ; o ; o := nextobj(o, floatingItem))
  3512.           global.floatingList += o;
  3513.  
  3514.     This should be placed in the preinit or init function.  Note that
  3515.     all objects which have location methods should be declared to be
  3516.     of class floatingItem:
  3517.  
  3518.       class floatingItem: object;
  3519.  
  3520.     This class doesn't do anything except serve as a flag that an
  3521.     object should be placed in the floatingList.
  3522.  
  3523. 2.0.7  12/01/92  MS-DOS bug fix release
  3524.  
  3525.   - The run-time occasionally missed the \ in an escape sequence in
  3526.     output strings.
  3527.  
  3528.   - The run-time couldn't operate in 132 column mode.
  3529.  
  3530.   - The run-time abnormally terminated in the file selection dialog
  3531.     when the dialog box was exactly filled.
  3532.  
  3533. 2.0.6  11/24/92  first general MS-DOS TADS 2.0 release
  3534.  
  3535.